「UOJ#117」 欧拉回路
欧拉回路 - 题目 - Universal Online Judge
题意:
给定有向图或无向图,求一条欧拉回路。
题解
心路历程:woc什么傻哔东西->哇真香我的吗!(逃
首先我知道很多人把欧拉回路和欧拉通路混为一谈,所以我以为这道题也是叫欧拉回路的欧拉迹
(欧拉迹比欧拉回路难打多少?!!!QAQ好吧也没多少
然后WA了2次才意识到这是真·欧拉回路。
改过来之后套版子上交:
//其中的dfs我是这么写的↓
void dfs(int x)
{
for(int i=h[x];i;i=a[i].f)
if(a[i].nod)
{
int x=a[i].nod;
a[i].nod=;
a[i^].nod=;
d[x]--;
d[a[i].e]--;
dfs(a[i].e);
st.push(x);
}
return;
}
肥肠标准的Hierholzer嘛。
然后光荣TLE(妈妈你骗我 你不是说Hierholzer是$O(E)$吗QAQ?!!!)
直到我从网上看不懂的大佬题解中看到了一个关键词:
当前弧优化
跟dinic里的当前弧优化一样,这里的当前弧优化也是为了避免每次重复循环很多次i
eg:
...
在这种情况下,我们每一次dfs()时,就会重新走一遍差不多所有连着1的边......
也就是说被光荣卡成$O(E^2)$了。
怎么办呢?
只需要让h[x]跟着i动就行了鸭!
//已经经历过了的i是绝无再扩展的可能了,那不如把h[x]推到前面去
于是,魔改之后:
void dfs(int x)
{
//for(R int i=h[x];i;i=a[i].f)
while(h[x])
{
int i=h[x];
h[x]=a[i].f;//更新h[x]
//剩下来的就跟以前一样了
if(a[i].nod)
{
int f=a[i].nod;
a[i].nod=;
a[i^].nod=;
d[x]--;
d[a[i].e]--;
dfs(a[i].e);
st[++tos]=f;//换成了数组模拟的栈
}
}
return;
}
时间直接变成原来的零头(3400ms+->32ms(n=1e5)
然后这道题就可以过掉啦。
/*
ID 题目 提交者 结果 用时 内存 语言 文件大小 提交时间 测评时间
#288775 #117. 欧拉回路 qwerta 100 534ms 14912kb C++ 3.0kb 2018-09-30 16:29:45 2018-09-30 16:29:47
*/
#include<iostream>
#include<cstdio>
#include<cmath>
#include<stack>
using namespace std;
#define R register
const int MAXN=1e5+;
const int MAXM=2e5+;
struct emm{
int e,f,nod;
}a[*MAXM];
int h[MAXN];
int tot=;
inline void con(int x,int y,int k)
{
a[++tot].f=h[x];
h[x]=tot;
a[tot].e=y;
a[tot].nod=k;
return;
}
int d[MAXN];
int st[*MAXM];
int tos=;
void dfs(int x)
{
//for(R int i=h[x];i;i=a[i].f)
while(h[x])
{
int i=h[x];
h[x]=a[i].f;
if(a[i].nod)
{
int f=a[i].nod;
a[i].nod=;
a[i^].nod=;
d[x]--;
d[a[i].e]--;
dfs(a[i].e);
st[++tos]=f;
}
}
return;
}
int tim=;
void dfss(int x)
{
//cout<<tos<<endl;
//for(R int i=h[x];i;i=a[i].f)
while(h[x])
{
int i=h[x];
h[x]=a[i].f;
if(a[i].nod)
{
int f=a[i].nod;
a[i].nod=;
d[x]--;
d[a[i].e]--;
dfss(a[i].e);
st[++tos]=f;
}
}
return;
}
int fa[MAXN];
inline int fifa(int x)
{
if(fa[x]==x)return x;
return fa[x]=fifa(fa[x]);
}
int rd[MAXN];
int cd[MAXN];
int main()
{
//freopen("a.in","r",stdin);
int t;
scanf("%d",&t);
if(t==)
{
int n,m;
scanf("%d%d",&n,&m);
for(R int i=;i<=n;++i)
fa[i]=i;
for(R int i=;i<=m;++i)
{
int u,v;
scanf("%d%d",&u,&v);
con(u,v,i);
con(v,u,-i);
d[u]++;
d[v]++;
fa[fifa(u)]=fifa(v);
}
//
for(R int i=;i<=n;++i)
if(d[i]%==){cout<<"NO";return ;}
int tag=;
for(R int i=;i<=n;++i)
if(d[i])
{
if(!tag)tag=fifa(i);
else if(fifa(i)!=tag){cout<<"NO";return ;}
}
//
int s=-;
for(R int i=;i<=n;++i)
if(d[i]){s=i;break;}
dfs(s);
cout<<"YES"<<endl;
while(tos)
{
printf("%d ",st[tos]);
--tos;
}
}
else
{
int n,m;
scanf("%d%d",&n,&m);
for(R int i=;i<=n;++i)
fa[i]=i;
for(R int i=;i<=m;++i)
{
int u,v;
scanf("%d%d",&u,&v);
con(u,v,i);
cd[u]++;
rd[v]++;
fa[fifa(u)]=fifa(v);
}
//
for(R int i=;i<=n;++i)
if(rd[i]!=cd[i]){cout<<"NO";return ;}
int tag=;
for(R int i=;i<=n;++i)
if(rd[i]||cd[i])
{
if(!tag)tag=fifa(i);
else if(fifa(i)!=tag){cout<<"NO";return ;}
}
//
int s=;
for(R int i=;i<=n;++i)
if(rd[i]||cd[i]){s=i;break;}
dfss(s);
cout<<"YES"<<endl;
while(tos)
{
printf("%d ",st[tos]);
--tos;
}
}
return ;
}
//其实删欧拉通路和那些调试之前有200+行(逃
「UOJ#117」 欧拉回路的更多相关文章
- 【UOJ 117】欧拉回路
#117. 欧拉回路 有一天一位灵魂画师画了一张图,现在要你找出欧拉回路,即在图中找一个环使得每条边都在环上出现恰好一次. 一共两个子任务: 这张图是无向图.(50分) 输入格式 第一行一个整数 t, ...
- 「UOJ 514」通用测评号(生成函数)
首先,题目中的过程可以看作:每次选择任意一个燃料仓,给它装填 \(1\) 单位的燃料,如果此时恰好 "填满" 了它,就给答案 \(+1\). 考虑 \(n\) 号燃料仓填满的概率, ...
- Solution -「UNR #5」「UOJ #671」诡异操作
\(\mathcal{Desciprtion}\) Link. 给定序列 \(\{a_n\}\),支持 \(q\) 次操作: 给定 \(l,r,v\),\(\forall i\in[l,r], ...
- Solution -「UOJ #46」玄学
\(\mathcal{Description}\) Link. 给定序列 \(\{a_n\}\) 和 \(q\) 次操作,操作内容如下: 给出 \(l,r,k,b\),声明一个修改方案,表示 ...
- Solution -「JOISC 2020」「UOJ #509」迷路的猫
\(\mathcal{Decription}\) Link. 这是一道通信题. 给定一个 \(n\) 个点 \(m\) 条边的连通无向图与两个限制 \(A,B\). 程序 Anthon ...
- Solution -「UR #21」「UOJ #632」挑战最大团
\(\mathcal{Description}\) Link. 对于简单无向图 \(G=(V,E)\),定义它是"优美"的,当且仅当 \[\forall\{a,b,c,d\ ...
- Solution -「UOJ #87」mx 的仙人掌
\(\mathcal{Description}\) Link. 给出含 \(n\) 个结点 \(m\) 条边的仙人掌图.\(q\) 次询问,每次询问给出一个点集 \(S\),求 \(S\) 内 ...
- Solution -「UR #2」「UOJ #32」跳蚤公路
\(\mathcal{Description}\) Link. 给定一个 \(n\) 个点 \(m\) 条边的带权有向图,每条边还有属性 \(s\in\{-1,0,1\}\).对于每个 \(u ...
- Solution -「UOJ #450」复读机
\(\mathcal{Description}\) Link. 求从 \(m\) 种颜色,每种颜色无限多的小球里选 \(n\) 个构成排列,使得每种颜色出现次数为 \(d\) 的倍数的排列方案 ...
随机推荐
- hdu5384
题意:给你n个母串.m个匹配串,让你求出对于每一个母串 全部匹配串出现的次数和. 思路:完全然全邝斌的模板啊... 凝视掉一行代码就能a... . 代码: #include <algorithm ...
- windows pipe
管道分为 匿名管道 和 命名管道 . 1.匿名管道仅仅能在父子进程间进行通信.不能在网络间通信,并且传输数据是单向的.仅仅能一端写,还有一端读. 2.命令管道能够在随意进程间通信.通信是双向的,随意一 ...
- java 发送微信客服消息
package com.baosight.wechat.service; import net.sf.json.JSONObject; import org.apache.commons.httpcl ...
- Jenkins和Maven构建持续集成
真是运维的福利,不用在敲Linux命令了 须要的工具:Linux或window.Jenkins.tomcat7.Jdk.maven.项目部署的war包 1.首先从Jenkins官网下载最新的Jenki ...
- icmp的程序(ping的实现)
code来源于<网络编程与分层协议设计> chap7 ICMP协议程序设计 ----没有理解,没有编译,只是敲了出来 ping.h #define ICMP_ECHOREPLY 0#def ...
- 韦东山 第9课第1节.u-boot分析之编译体验 http://www.100ask.net/index.html
http://www.100ask.net/index.html 韦东山官网网址 http://wenku.baidu.com/view/ae78a00390c69ec3d5bb75ce.html h ...
- IOS版App的控件元素定位
前言 Android版App的控件元素可以通过Android studio自带的工具uiautomatorviewer来协助定位! IOS版App的控件元素可以通过Appium来实现(未实现),或ap ...
- 九度OJ 1110:小白鼠排队 (排序)
时间限制:1 秒 内存限制:32 兆 特殊判题:否 提交:1734 解决:1054 题目描述: N只小白鼠(1 <= N <= 100),每只鼠头上戴着一顶有颜色的帽子.现在称出每只白鼠的 ...
- Connection Phase Packets
Connection Phase Packets https://dev.mysql.com/doc/internals/en/connection-phase-packets.html#packet ...
- Cocos2d-x动画播放(序列帧)
简介 Cocos2d-x中,动画的具体内容是依靠精灵显示出来的,为了显示动态图片,我们需要不停切换精灵显示的内容,通过把静态的精灵变为动画播放器从而实现动画效果.动画由帧组成,每一帧都是一个纹理,我们 ...