欧拉回路 - 题目 - 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」 欧拉回路的更多相关文章

  1. 【UOJ 117】欧拉回路

    #117. 欧拉回路 有一天一位灵魂画师画了一张图,现在要你找出欧拉回路,即在图中找一个环使得每条边都在环上出现恰好一次. 一共两个子任务: 这张图是无向图.(50分) 输入格式 第一行一个整数 t, ...

  2. 「UOJ 514」通用测评号(生成函数)

    首先,题目中的过程可以看作:每次选择任意一个燃料仓,给它装填 \(1\) 单位的燃料,如果此时恰好 "填满" 了它,就给答案 \(+1\). 考虑 \(n\) 号燃料仓填满的概率, ...

  3. Solution -「UNR #5」「UOJ #671」诡异操作

    \(\mathcal{Desciprtion}\)   Link.   给定序列 \(\{a_n\}\),支持 \(q\) 次操作: 给定 \(l,r,v\),\(\forall i\in[l,r], ...

  4. Solution -「UOJ #46」玄学

    \(\mathcal{Description}\)   Link.   给定序列 \(\{a_n\}\) 和 \(q\) 次操作,操作内容如下: 给出 \(l,r,k,b\),声明一个修改方案,表示 ...

  5. Solution -「JOISC 2020」「UOJ #509」迷路的猫

    \(\mathcal{Decription}\)   Link.   这是一道通信题.   给定一个 \(n\) 个点 \(m\) 条边的连通无向图与两个限制 \(A,B\).   程序 Anthon ...

  6. Solution -「UR #21」「UOJ #632」挑战最大团

    \(\mathcal{Description}\)   Link.   对于简单无向图 \(G=(V,E)\),定义它是"优美"的,当且仅当 \[\forall\{a,b,c,d\ ...

  7. Solution -「UOJ #87」mx 的仙人掌

    \(\mathcal{Description}\)   Link.   给出含 \(n\) 个结点 \(m\) 条边的仙人掌图.\(q\) 次询问,每次询问给出一个点集 \(S\),求 \(S\) 内 ...

  8. Solution -「UR #2」「UOJ #32」跳蚤公路

    \(\mathcal{Description}\)   Link.   给定一个 \(n\) 个点 \(m\) 条边的带权有向图,每条边还有属性 \(s\in\{-1,0,1\}\).对于每个 \(u ...

  9. Solution -「UOJ #450」复读机

    \(\mathcal{Description}\)   Link.   求从 \(m\) 种颜色,每种颜色无限多的小球里选 \(n\) 个构成排列,使得每种颜色出现次数为 \(d\) 的倍数的排列方案 ...

随机推荐

  1. Redis Sentinel 情况下bind地址设置

    Redis Sentinel 情况下bind地址设置 1个master,2个slave,3个sentinel的情况下,注意bind地址的时候不要写0.0.0.0,会导致绑定多个地址, 然后sentin ...

  2. web图片转换小工具制作

    HTML <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <titl ...

  3. js逻辑非同时两次使用 !!null

    今天遇到了“!!null”的写法,百度没有找到直接的解释,翻书在<javascript高级设计>P44找到了相应的解释: 同时使用两个逻辑非操作符,实际上就会模拟Boolean()转型函数 ...

  4. MySQL提示Access denied for user &#39;&#39;@&#39;localhost&#39;”的解决

    记得那时由于没有网络,把rootpassword改错了写成了: update user set password="122" where user="root" ...

  5. Linaro/Yocto/Openwrt

    http://en.wikipedia.org/wiki/Linaro Linaro From Wikipedia, the free encyclopedia     This article ap ...

  6. POJ 3335 Rotating Scoreboard(半平面交 多边形是否有核 模板)

    题目链接:http://poj.org/problem? id=3335 Description This year, ACM/ICPC World finals will be held in a ...

  7. java ArrayList倒序

    用Collections.reverse(list)即可.如:List<String> list = Arrays.asList(new String[] {"aa", ...

  8. sublime 快捷键 汇总--长期

    Ctrl+P 输入当前项目中的文件名,快速搜索文件 Ctrl+G 输入数字跳转到该行代码 Ctrl+R 输入关键字,查找文件中的函数名 Ctrl+: 输入关键字,查找文件中的变量名.属性名等 Ctrl ...

  9. RYU改动监听port Mininet在custom自建拓扑和连接到指定控制器命令解释

    1.RYU控制器改动监听port 在ryu/ryu/ofproto以下的ofproto_common.py watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvc ...

  10. c#生成试卷。。。

    .net下,操作Word的插件有NPOI,Spire,一版大家经常用的是NPOI,我在着手开发的时候,优先考虑的也是NPOI,然而时间比较着急,没有找到NPOI支持2003版本, 就放弃了,从网上发行 ...