1. 程式人生 > >uoj117:歐拉回路——題解

uoj117:歐拉回路——題解

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 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; }

uoj117:歐拉回路——題解