板子:
#include<set>
#include<map>
#include<deque>
#include<queue>
#include<stack>
#include<cmath>
#include<ctime>
#include<bitset>
#include<string>
#include<vector>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<climits>
#include<complex>
#include<iostream>
#include<algorithm>
#define ll long long
using namespace std;
const int maxn = 11000;
const int maxm = 510000;
int n,m;
struct edge
{
int y,nex;
edge(){}
edge(const int _y,const int _nex){y=_y;nex=_nex;}
}a[maxm]; int len,fir[maxn];
inline void ins(const int x,const int y){a[++len]=edge(y,fir[x]);fir[x]=len;}
int fa[maxn];
int findfa(const int x){return fa[x]==x?x:fa[x]=findfa(fa[x]);}
void unit(int x,int y){fa[x=findfa(x)]=findfa(y);}
int nex[maxn],spouse[maxn],mark[maxn],v[maxn],cnt;
int LCA(int x,int y)
{
++cnt;
while(x)
{
v[x=findfa(x)]=cnt;
x=nex[spouse[x]];
}
while(y)
{
if(v[y=findfa(y)]==cnt) return y;
y=nex[spouse[y]];
}
}
int q[maxn],tail;
void group(int x,const int &tp)
{
while(x!=tp)
{
int b=spouse[x],c=nex[b];
if(findfa(c)!=tp) nex[c]=b;
if(mark[b]==2) mark[q[++tail]=b]=1;
if(mark[c]==2) mark[q[++tail]=c]=1;
unit(x,b); unit(b,c);
x=c;
}
}
bool augment(const int s)
{
for(int i=1;i<=n;i++) mark[i]=nex[i]=0,fa[i]=i;
q[tail=1]=s;
for(int i=1;i<=tail;i++)
{
const int x=q[i];
for(int k=fir[x];k;k=a[k].nex)
{
const int y=a[k].y; if(spouse[y]==x) continue;
if(findfa(x)==findfa(y)) continue;
if(mark[y]==2) continue;
if(mark[y]==0)
{
if(!spouse[y])
{
int p1=y,p2=x;
while(p1)
{
int z=spouse[p2];
spouse[p1]=p2; spouse[p2]=p1;
p1=z,p2=nex[p1];
}
return true;
}
else
{
nex[y]=x;
mark[y]=2;
mark[q[++tail]=spouse[y]]=1;
}
}
else
{
int tp=LCA(x,y);
if(findfa(x)!=tp) nex[x]=y;
if(findfa(y)!=tp) nex[y]=x;
group(x,tp); group(y,tp);
}
}
}
return false;
}
int main()
{
scanf("%d%d",&n,&m);
for(int i=1;i<=m;i++)
{
int x,y; scanf("%d%d",&x,&y);
ins(x,y); ins(y,x);
}
int re=0;
for(int i=1;i<=n;i++)
if(!spouse[i]&&augment(i)) re++;
printf("%d\n",re);
for(int i=1;i<=n;i++) printf("%d ",spouse[i]);
return 0;
}