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 }
时间: 2024-10-06 21:53:09