题目要求的是加最少的边使得所有点的入度和出度都是偶数。
加边就是把每两个度数为奇数的点连起来。
对于加完边后的图,若不考虑边的方向,则所有点的度都是偶数,这就一定会存在欧拉回路,找到这条欧拉回路,如果这条欧拉回路中包含偶数个边,那么一定可以构造出符合要求的解,如果是奇数,那么就随便找一个点给它加一个自环,这样边就变成了偶数个,即可构造出解。
#include<cstring>
#include<cstdio>
#include<algorithm>
#include<iostream>
#define N 100005
#include<vector>
#include<queue>
using namespace std;
int out[N],deg[N];
queue<pair<int,int> >q[N];
bool vis[N*3];
struct A
{
int a,b;
}ans[3*N];
int top;
void euler(int u)
{
int i,v;
pair<int,int>nw;
while(!q[u].empty()){
nw=q[u].front(); q[u].pop();
v=nw.first;
if(vis[nw.second]) continue;
vis[nw.second]=1;
euler(v);
ans[++top].a=u;
ans[top].b=v;
}
}
int main()
{
int n,m,i,a,b;
scanf("%d%d",&n,&m);
int number=0;
for(i=1;i<=m;i++) {
scanf("%d%d",&a,&b);
q[a].push(make_pair(b,++number));
q[b].push(make_pair(a,number));
deg[a]++; deg[b]++;
}
int last=-1;
for(i=1;i<=n;i++){
if(deg[i]&1){
if(last==-1) last=i;
else {
q[last].push(make_pair(i,++number));
q[i].push(make_pair(last,number));
last=-1;
deg[last]++; deg[i]++;
}
}
}
if(number&1){
q[1].push(make_pair(1,++number));
}
euler(1);
cout<<top<<endl;
for(i=1;i<=top;i++){
if(i&1) printf("%d %d\n",ans[i].a,ans[i].b);
else printf("%d %d\n",ans[i].b,ans[i].a);
}
return 0;
}