这题说的是给了n个点 和m条边, 这m条边是无向的,任务是将这些边变成有向的,并且添加最少的有向边使得这个图中每个点的入度为偶数, 出度为偶数。

我们可以考虑使用欧拉回路来解决这个问题,这样说,假如一个图如果满足欧拉回路,那么 a b c d a , a - > b <-c ->d <-a 只要这样一下就解决了问题。我们知道要使得这个图是欧拉回路,必须满足每个点的度数为偶数 我们将度数为奇数的点, 两两一对 形成一条边。然后跑一个欧拉回路,接着像上面举得例子一样 同时给一个点增加两个出度或者增加两个入度, 但是可能会有问题存在就是起始点 我们可以知道当边为奇数的时候,起点的入度和出度为奇数,我们在给他俩一个自环就解决了。

 1 #include <iostream>
 2 #include <algorithm>
 3 #include <string.h>
 4 #include <cstdio>
 5 using namespace std;
 6 const int maxn=100000+10;
 7 const int M =500000+10;
 8 int G[maxn],next[M*2],num,To[M*2],d[maxn],a[maxn],nn;
 9 bool use[M*2];
10 struct Edge{  int form,to ;}top[M];
11 void add_edg(int x, int y){
12     num++;
13     next[M+num] = G[x];
14     G[x]=M+num; To[M+num] = y;
15     next[M-num] = G[y];
16     G[y] = M-num; To[M-num] =x;
17 }
18 void dfs(int u){
19 
20     while(G[u]){
21         if(!use[G[u]]){
22               use[G[u]] = use[M*2-G[u]] = true;
23               int to = To[G[u]];
24               dfs(To[ G[u] ]);
25               top[nn++]=(Edge){u,to};
26         }
27         G[u]=next[ G[u] ];
28     }
29 }
30 int main()
31 {
32     int n,m;
33     while(scanf("%d%d",&n,&m)==2){
34          memset(d,0,sizeof(d));
35          memset(G,0,sizeof(G));
36          memset(use,false,sizeof(use));
37          num=nn=0;
38          for(int i=0; i<m; i++){
39              int a,b;
40              scanf("%d%d",&a,&b);
41              d[a]++; d[b]++;
42              add_edg(a,b);
43          }
44          int un = 0;
45          for(int i=1; i<=n; i++ )
46          if(d[i]&1){
47               a[un++]=i;
48          }
49          int cound=m;
50          for(int i =0; i<un; i+=2){
51               add_edg(a[i],a[i+1]);cound++;
52          }
53          if(cound&1)cound++;
54          printf("%d\n",cound);
55          dfs(1);
56          for(int i =0; i<nn; i++)
57             if(i&1) printf("%d %d\n",top[i].form,top[i].to);
58          else printf("%d %d\n",top[i].to,top[i].form);
59          if( (nn&1) ) printf("1 1\n");
60     }
61     return 0;
62 }