- 欧拉回路中的点入度都等于出度,所以我们可以在图中构造一条欧拉回路
- 考虑到图中度数为奇数的点有偶数个,所以我们把两两度数为奇数的点连一条边,这样所有点的度数都是偶数了
- 答案就是度数为偶数的点的个数,跑一遍欧拉回路即可
- 因为奇数点之间的连边不影响偶数点,而欧拉回路保证所有点入度等于出度,所以原图中的偶数点都符合条件
- 注意图可能不连通
Code
#include<bits/stdc++.h>
#define rep(i,a,b) for(int i=(a);i<=(b);i++)
using namespace std;
const int N=2e5;
struct node{int y,n,id,pos;}e[N];
int lin[N],du[N],S[N],v[N],A[N],last=0,top=0,ans=0,len=1,n,m,x,y;
void read(int x,int y,int i){
e[++len].y=y,e[len].n=lin[x],e[len].pos=i,e[len].id=0,lin[x]=len;
e[++len].y=x,e[len].n=lin[y],e[len].pos=i,e[len].id=1,lin[y]=len;
}
void euler(int s){
S[++top]=s;
while(top){
int x=S[top],i=lin[x];
while(i&&v[i])i=e[i].n;
if(i){
S[++top]=e[i].y;
v[i]=v[i^1]=1;
A[e[i].pos]=e[i].id;
lin[x]=e[i].n;
}else top--;
}
}
int main()
{
scanf("%d%d",&n,&m);
rep(i,1,m){
scanf("%d%d",&x,&y);
du[x]++,du[y]++;
read(x,y,i);
}
rep(i,1,n){
if(du[i]&1){
if(last)read(last,i,0),last=0;
else last=i;
}else ans++;
}
rep(i,1,n)euler(i);
printf("%d\n",ans);
rep(i,1,m)printf("%d",A[i]);
return 0;
}