uoj117:歐拉回路——題解
阿新 • • 發佈:2017-11-18
ans edge ace urn truct iostream col void cto
http://uoj.ac/problem/117
(作為一道歐拉回路的板子題,他成功的令我學會了歐拉回路)
(然而我不會背……)
就兩件事:
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 intM=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; }
uoj117:歐拉回路——題解