UOJ117:欧拉回路——题解
(作为一道欧拉回路的板子题,他成功的令我学会了欧拉回路)
(然而我不会背……)
就两件事:
1.无向图为欧拉图,当且仅当为连通图且所有顶点的度为偶数。
2.有向图为欧拉图,当且仅当其基图(将有向边变为无向边的图)连通,且所有顶点的入度等于出度。
这里注意一下:
1.卡时间,所以链前循环的i要写成&i。
2.那么就需要早点将i%2的值存下来。
#include<stack> #include<cstdio> #include<cstring> #include<vector> #include<iostream> #include<algorithm> using namespace std; typedef long long ll; inline int read(){ int x=0,w=1;char ch=0; while(ch<'0'||ch>'9'){if(ch=='-')w=-1;ch=getchar();} while(ch>='0'&&ch<='9'){x=(x<<1)+(x<<3)+ch-'0';ch=getchar();} return x*w; } const int N=100010; const int M=200010; struct node{ int to; int nxt; }edge[M*2]; int cnt=1,head[N]; void add(int u,int v){ cnt++; edge[cnt].to=v; edge[cnt].nxt=head[u]; head[u]=cnt; return; } int t; int indeg[N],outdeg[N]; bool vis[M]; std::vector<int>ans; void dfs(int u){ for(int &i=head[u];i;i=edge[i].nxt){ int v=edge[i].to; int num; if(t==1)num=i/2; else num=i-1; bool sig=i%2; if(!vis[num]){ vis[num]=1; dfs(v); if(t==1){ if(sig)ans.push_back(-num); else ans.push_back(num); }else{ ans.push_back(num); } } } return; } int main(){ t=read(); int n=read(); int m=read(); for(int i=1;i<=m;i++){ int u=read(); int v=read(); add(u,v); outdeg[u]++;indeg[v]++; if(t==1){ add(v,u); } } if(t==1){ for(int i=1;i<=n;i++){ if((indeg[i]+outdeg[i])%2){ printf("NO\n"); return 0; } } }else{ for(int i=1;i<=n;i++){ if(indeg[i]!=outdeg[i]){ printf("NO\n"); return 0; } } } for(int i=1;i<=n;i++){ if(head[i]){ dfs(i); break; } } if(ans.size()!=m){ printf("NO\n"); return 0; } printf("YES\n"); for(int i=m-1;i>=0;i--){ printf("%d ",ans[i]); } printf("\n"); return 0; }