题意:给一个无重边的无向图,给边定向,使得定向后的有向图中满足出度等于入度的点的个数最多。输出点的个数以及各条边的方向。
解法:已知一个无向图的联通分量中,奇度点的个数一定是偶数。故可向原图中奇度点之间加边,最后跑出欧拉回路就行,输出边的时候,注意自己添加的边不要输出即可。
#include <bits/stdc++.h>
using namespace std;
typedef unsigned int uii;
typedef pair<int,int> pii;
const int maxn=201;
struct ee {
int v,id;
bool ok,va;
ee(){}
ee(int v,int id,bool ok,bool va=false):v(v),id(id),ok(ok){}
};
int t,n,m,a,b,rn,cnt[maxn];
uii sta[maxn];
vector<ee> vec[maxn];
stack<int> stk;
int main()
{
scanf("%d",&t);
while (t--) {
memset(sta,0,sizeof sta);
memset(cnt,0,sizeof cnt);
scanf("%d%d",&n,&m);
rn=n;
for (int i=1;i<=n;++i)
vec[i].clear();
for (int i=0;i<m;++i) {
scanf("%d%d",&a,&b);
vec[a].push_back(ee(b,vec[b].size(),1));
vec[b].push_back(ee(a,vec[a].size()-1,1));
++cnt[a];
++cnt[b];
}
int i=-1;
for (int j=1;j<=n;++j)
if (cnt[j]&1) {
--rn;
if (i==-1)
i=j;
else {
vec[j].push_back(ee(i,vec[i].size(),0));
vec[i].push_back(ee(j,vec[j].size()-1,0));
}
}
printf("%d\n",rn);
for (int i=1;i<=n;++i) {
stk.push(i);
while (!stk.empty()) {
int u=stk.top();
if (sta[u]==vec[u].size())
stk.pop();
for (uii &i=sta[u];i<vec[u].size();++i)
if (!vec[u][i].va) {
vec[u][i].va=true;
vec[vec[u][i].v][vec[u][i].id].va=true;
if (vec[u][i].ok)
printf("%d %d\n",u,vec[u][i].v);
stk.push(vec[u][i].v);
break;
}
}
}
}
return 0;
}