欧拉回路-学习笔记

i207M

2019-07-11 21:21:43

Personal

~~重新学习欧拉回路~~ ### 无向图 每个点的度数是偶数。 ### 有向图 每个点的出度入度相等。 --- ## 求法 从任意一个有边的点出发,沿着每条没有走过的边dfs,记录经过的边的**后序**历序,然后**reverse**一下就是欧拉回路的边序了。 记得要&i=head[x],不然会退化为$O(m^2)$,这样就需要用一个临时变量记一下边的编号了。 ```cpp const int N=100005,M=200005*2; int head[N],cnte,v[M],nx[M]; il void adde(int uu,int vv) { v[++cnte]=vv,nx[cnte]=head[uu],head[uu]=cnte; } int n,m; bool vis[M]; int st[M],tp; void dfs1(int x) { for(ri &i=head[x],t;i;i=nx[i]) { if(vis[i>>1]) continue; vis[i>>1]=1,t=i; dfs1(v[i]); st[++tp]=t; } } void dfs2(int x) { for(ri &i=head[x],t;i;i=nx[i]) { if(vis[i]) continue; vis[i]=1,t=i; dfs2(v[i]); st[++tp]=t; } } il void gun() {puts("NO"); exit(0);} int ru[N],cu[N]; signed main() { #ifdef M207 freopen("in.in","r",stdin); #endif int typ; in(typ); cnte=typ==1?1:0; in(n),in(m); for(ri i=1,a,b;i<=m;++i) { in(a),in(b); adde(a,b); ++cu[a]; if(typ==1) adde(b,a),++cu[b]; else ++ru[b]; } if(typ==1) { for(ri i=1;i<=n;++i) if(cu[i]&1) gun(); } else { for(ri i=1;i<=n;++i) if(cu[i]!=ru[i]) gun(); } for(ri i=1;i<=n;++i) if(head[i]) { if(typ==1) dfs1(i); else dfs2(i); break; } if(tp!=m) gun(); else { puts("YES"); reverse(st+1,st+1+tp); if(typ==1) { for(ri i=1;i<=tp;++i) out((st[i]>>1)*(st[i]&1?-1:1),' '); } else { for(ri i=1;i<=tp;++i) out(st[i],' '); } } return 0; } ```