「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\) 的倍数的排列方案 ...
随机推荐
- 赞一下TMS Software 和 AdvStringGrid
非常久前给Support发Email问能不能在设计期给AdvStringGrid标题加个数字标识.每次我都是自己改代码加上去.这次升级到新版本号,没想到增加了这个功能: 功能虽小可是非常有用,非常多的 ...
- 解决"Subquery returns more than 1 row"sql查询错误
http://blog.csdn.net/c517984604/article/details/7052186 [Err] 1242 - Subquery returns more than 1 ro ...
- Selenium系列之--07 操作远程浏览器
Selenium远程控制浏览,可以通过如下两种方式实现,本质上都是Selenium Grid a. 客户机启Selenium Standalone Server 作为远程服务,服务端通过调用Remo ...
- Jenkins系列之-—08 实现SQL脚本批量执行
公司内部推广DevOps,所有目前在维护阶段和开发阶段项目全部配置上了自动发布.采用Jenkins+SVN+ANT,之后批量执行SQL语句的实现提上日程 一.环境 Linux环境 安装ANT工具,且下 ...
- 【随想】android是个什么东西,andorid机制随想
优秀程序猿的天性就是好奇,软件是怎么运作的.屏幕是怎样显示的.桌面窗口为何能如此人性化的被鼠标拖动? 假设你常常会有这样一些问题迸发在脑海中,恭喜你,你是一名非常有潜力的程序猿. 我在大学读的是自己主 ...
- 【Sprint2 每日Scrum】 第一天(4.22)Sprint2计划会议成果
Sprint2计划会议成果 从今天起我们就开始正式的Sprint2之旅了,经过上一次Sprint1的冲刺计划和几天的调整,我们已经大致了解了敏捷开发的流程和思想,并将我们的TD学生助手做出了大致的框架 ...
- Python生成器定义
通过列表生成式,我们可以直接创建一个列表.但是,受到内存限制,列表容量肯定是有限的.而且,创建一个包含100万个元素的列表,不仅占用很大的存储空间,如果我们仅仅需要访问前面几个元素,那后面绝大多数元素 ...
- C++再次理解虚表
#include <iostream> using namespace std; class Base { public: virtual void fun1() { cout <& ...
- 第一个php小程序(学习)
</pre><pre name="code" class="php"><? php $b=array("name&quo ...
- 【剑指Offer学习】【面试题62:序列化二叉树】
题目:请实现两个函数,分别用来序列化和反序列化二叉树. 解题思路 通过分析解决前面的面试题6.我们知道能够从前序遍历和中序遍历构造出一棵二叉树.受此启示.我们能够先把一棵二叉树序列化成一个前序遍历序列 ...