欧拉回路 - 题目 - 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. hdu5384

    题意:给你n个母串.m个匹配串,让你求出对于每一个母串 全部匹配串出现的次数和. 思路:完全然全邝斌的模板啊... 凝视掉一行代码就能a... . 代码: #include <algorithm ...

  2. windows pipe

    管道分为 匿名管道 和 命名管道 . 1.匿名管道仅仅能在父子进程间进行通信.不能在网络间通信,并且传输数据是单向的.仅仅能一端写,还有一端读. 2.命令管道能够在随意进程间通信.通信是双向的,随意一 ...

  3. java 发送微信客服消息

    package com.baosight.wechat.service; import net.sf.json.JSONObject; import org.apache.commons.httpcl ...

  4. Jenkins和Maven构建持续集成

    真是运维的福利,不用在敲Linux命令了 须要的工具:Linux或window.Jenkins.tomcat7.Jdk.maven.项目部署的war包 1.首先从Jenkins官网下载最新的Jenki ...

  5. icmp的程序(ping的实现)

    code来源于<网络编程与分层协议设计> chap7 ICMP协议程序设计 ----没有理解,没有编译,只是敲了出来 ping.h #define ICMP_ECHOREPLY 0#def ...

  6. 韦东山 第9课第1节.u-boot分析之编译体验 http://www.100ask.net/index.html

    http://www.100ask.net/index.html 韦东山官网网址 http://wenku.baidu.com/view/ae78a00390c69ec3d5bb75ce.html h ...

  7. IOS版App的控件元素定位

    前言 Android版App的控件元素可以通过Android studio自带的工具uiautomatorviewer来协助定位! IOS版App的控件元素可以通过Appium来实现(未实现),或ap ...

  8. 九度OJ 1110:小白鼠排队 (排序)

    时间限制:1 秒 内存限制:32 兆 特殊判题:否 提交:1734 解决:1054 题目描述: N只小白鼠(1 <= N <= 100),每只鼠头上戴着一顶有颜色的帽子.现在称出每只白鼠的 ...

  9. Connection Phase Packets

    Connection Phase Packets https://dev.mysql.com/doc/internals/en/connection-phase-packets.html#packet ...

  10. Cocos2d-x动画播放(序列帧)

    简介 Cocos2d-x中,动画的具体内容是依靠精灵显示出来的,为了显示动态图片,我们需要不停切换精灵显示的内容,通过把静态的精灵变为动画播放器从而实现动画效果.动画由帧组成,每一帧都是一个纹理,我们 ...