1. 程式人生 > >51nod 1967 路徑定向(不錯的歐拉回路)

51nod 1967 路徑定向(不錯的歐拉回路)

cnblogs 偶數 ret mes stack ostream lin .html pre

http://www.51nod.com/onlineJudge/questionCode.html#!problemId=1967

題意:

技術分享

思路:

出度=入度,這很容易想到歐拉回路,事實上,這道題目也確實是用歐拉回路來做的,之前一直覺得應該用網絡流來做,可惜想不出,後來看官方題解說也是可以的,但是復雜度太高。

對於每條邊,先假設它為無向邊,奇點的個數肯定是偶數個,對於這些奇點,我們可以兩兩連條邊,使它們變成偶點,這樣一來就肯定存在歐拉回路了,跑一遍就可以了。新加的邊是不會影響結果的。

這道題目有點卡時間,用printf輸出會超時,得用putchar。

 1 #include<iostream>
 2
#include<algorithm> 3 #include<cstring> 4 #include<cstdio> 5 #include<sstream> 6 #include<vector> 7 #include<stack> 8 #include<queue> 9 #include<cmath> 10 #include<map> 11 #include<set> 12 using namespace std; 13 typedef long
long ll; 14 typedef pair<int,ll> pll; 15 const int inf = 0x3f3f3f3f; 16 const int maxn=1e6+5; 17 const int mod=1e9+7; 18 19 int n, m; 20 int vis[maxn]; 21 int ans[maxn]; 22 int flag[maxn]; 23 int degree[maxn]; 24 25 struct node 26 { 27 int u,v; 28 }e[maxn]; 29 30 vector<int
> G[maxn],p; 31 32 void dfs(int x) 33 { 34 vis[x]=1; 35 for(int i=0;i<G[x].size();i++) 36 { 37 int idx=G[x][i]; 38 if(flag[idx]) continue; 39 if(e[idx].u==x) {flag[idx]=1;dfs(e[idx].v);} 40 else {flag[idx]=2;dfs(e[idx].u);} 41 } 42 } 43 44 int main() 45 { 46 //freopen("in.txt","r",stdin); 47 scanf("%d%d",&n,&m); 48 for(int i=0;i<m;i++) 49 { 50 int u,v; 51 scanf("%d%d",&u,&v); 52 e[i].u=u, e[i].v=v; 53 G[u].push_back(i); 54 G[v].push_back(i); 55 degree[u]++; 56 degree[v]++; 57 } 58 for(int i=1;i<=n;i++) if(degree[i]&1) p.push_back(i); 59 for(int i=0;i<p.size();i+=2) 60 { 61 e[i/2+m].u=p[i], e[i/2+m].v=p[i+1]; 62 G[p[i]].push_back(i/2+m); 63 G[p[i+1]].push_back(i/2+m); 64 } 65 for(int i=1;i<=n;i++) 66 { 67 if(!vis[i]) dfs(i); 68 } 69 printf("%d\n",n-p.size()); 70 for(int i=0;i<m;i++) 71 { 72 if(flag[i]==1) putchar(0); 73 else putchar(1); 74 } 75 printf("\n"); 76 return 0; 77 }

51nod 1967 路徑定向(不錯的歐拉回路)