codeforces 723E (欧拉回路)

Problem One-Way Reform

题目大意

  给一张n个点,m条边的无向图,要求给每条边定一个方向,使得最多的点入度等于出度,要求输出方案。

解题分析

  最多点的数量就是入度为偶数的点。

  将入度为奇数的点每两个组成一队,连一条无向边,之后求出欧拉回路即可。

参考程序

  1 #include <map>
  2 #include <set>
  3 #include <stack>
  4 #include <queue>
  5 #include <cmath>
  6 #include <ctime>
  7 #include <string>
  8 #include <vector>
  9 #include <cstdio>
 10 #include <cstdlib>
 11 #include <cstring>
 12 #include <cassert>
 13 #include <iostream>
 14 #include <algorithm>
 15 #pragma comment(linker,"/STACK:102400000,102400000")
 16 using namespace std;
 17 
 18 #define N 1000
 19 #define E 50000
 20 #define LL long long
 21 #define lson l,m,rt<<1
 22 #define rson m+1,r,rt<<1|1 
 23 #define clr(x,v) memset(x,v,sizeof(x));
 24 #define bitcnt(x) __builtin_popcount(x)
 25 #define rep(x,y,z) for (int x=y;x<=z;x++)
 26 #define repd(x,y,z) for (int x=y;x>=z;x--)
 27 const int mo  = 1000000007;
 28 const int inf = 0x3f3f3f3f;
 29 const int INF = 2000000000;
 30 /**************************************************************************/ 
 31 
 32 int T,n,m,sum;
 33 int lt[N],deg[N],f[N],dict[E];
 34 struct line{
 35     int u,v,nt,flag;
 36 }eg[E];
 37 void add(int u,int v)
 38 {
 39     eg[++sum]=(line){u,v,lt[u],0}; lt[u]=sum; deg[v]++;
 40 }
 41 vector <int> vct,path;
 42 stack <int> Q;
 43 void dfs(int u)
 44 {
 45     int v=0;
 46     Q.push(u);
 47     f[u]=1;
 48     for (int i=lt[u];i;i=eg[i].nt)
 49     {
 50         if (eg[i].flag) continue;
 51         eg[i].flag=eg[i^1].flag=1; dict[i/2]=i; lt[u]=i;
 52         v=eg[i].v; 
 53         dfs(v);
 54         break;
 55     }
 56 }
 57 void work(int S)
 58 {
 59     while (!Q.empty()) Q.pop();
 60     Q.push(S);
 61     while (!Q.empty())
 62     {
 63         int u=Q.top(),flag=0; Q.pop();
 64         for (int i=lt[u];i;i=eg[i].nt)
 65         {
 66             if (eg[i].flag) continue;
 67             flag=1;
 68             break;        
 69         }
 70         if (flag) dfs(u); else path.push_back(u);
 71     }
 72 }
 73 int main()
 74 {
 75     cin>>T;
 76     while (T--)
 77     {
 78         cin>>n>>m; 
 79         int ans=n;
 80         rep(i,1,n) deg[i]=lt[i]=0; sum=1;
 81         rep(i,1,m)
 82         {
 83             int u,v;
 84             scanf("%d%d",&u,&v);
 85             add(u,v); add(v,u);
 86         }
 87         vct.clear(); path.clear();
 88         rep(i,1,n) if (deg[i] & 1)
 89         {
 90             ans--;
 91             vct.push_back(i);
 92         }
 93         for (int i=0;i<vct.size();i+=2)
 94         {
 95             add(vct[i],vct[i+1]);
 96             add(vct[i+1],vct[i]);
 97         }
 98         clr(f,0);
 99         rep(i,1,n) if (f[i]==0) work(i);
100         printf("%d
",ans);
101         rep(i,1,m) printf("%d %d
",eg[dict[i]].u,eg[dict[i]].v);
102         //for (auto v:path) printf("%d ",v);
103     }
104 }
View Code
原文地址:https://www.cnblogs.com/rpSebastian/p/5934039.html