题意:给你一张n个点m条边的联通无向图,现在你需要将每一条边确定一个方向,使得每个点的出度和入度都为偶数。初始给定的图不一定有解,你需要给这张图加上尽可能少的边,使得新图有解,并输出一个方案。
思路:欧拉回路的性质之一是所有的点的度都是偶数,那么这题就转换成求欧拉回路。那么如何保证出度入度都为偶数呢?在输出欧拉回路的时候,一正一反的输出即可,这题需要注意的是欧拉回路有可能出现自环的情况,如下图:
#include <bits/stdc++.h>
using namespace std;
const int maxn = 4e5+100;
int tot_edge = 0;
multiset<int>G[maxn];
vector<int>odd,ans;
void dfs(int u)
{
while(!G[u].empty())
{
int v = *G[u].begin();
G[u].erase(G[u].begin());
G[v].erase(G[v].find(u));
dfs(v);
}
ans.push_back(u);
}
int main()
{
int n,m;
scanf("%d%d",&n,&m);
for(int i=1;i<=m;i++)
{
int u,v;
scanf("%d%d",&u,&v);
G[u].insert(v);
G[v].insert(u);
tot_edge++;
}
for(int i=1;i<=n;i++)
if(G[i].size() & 1)odd.push_back(i);
for(int i=0;i<(int)odd.size()-1;i+=2)
{
G[odd[i]].insert(odd[i+1]);
G[odd[i+1]].insert(odd[i]);
tot_edge++;
}
if(tot_edge & 1)G[1].insert(1),G[1].insert(1),tot_edge++;
dfs(1);
printf("%d\n",tot_edge);
for(int i=0;i<(int)ans.size()-1;i++)
{
if(i & 1)printf("%d %d\n",ans[i],ans[i+1]);
else printf("%d %d\n",ans[i+1],ans[i]);
}
return 0;
}