全程在膜scpointer的代码,真是太强了,虽然说是看完代码才开始写的,但是一有一点点不一样就会 WA/TLE
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<queue>
using namespace std;
#define maxn 800005
int pre[maxn],to[maxn],next[maxn],tip;
int match[maxn],link[maxn],belong[maxn],type[maxn],vis[maxn];
int n,m,ans=0;
queue<int> Q;
inline int RD()
{
char ch;
int res=0;
ch=getchar();
while(ch>'9'||ch<'0')ch=getchar();
res=ch-'0';
while((ch=getchar())<='9'&&ch>='0')res=res*10+ch-'0';
return res;
}
void addedge(int x,int y)
{
static int counter=0;
next[++counter]=pre[x],pre[x]=counter,to[counter]=y;
next[++counter]=pre[y],pre[y]=counter,to[counter]=x;
}
int find(int now)
{
return now==belong[now]?now:belong[now]=find(belong[now]);
}
int LCA(int x,int y)
{
static int count=0;
count++;
while(1)
{
if(x)
{
x=find(x);
if(vis[x]==count)return x;
vis[x]=count;
x=link[match[x]];
}
swap(x,y);
}
}
void cnnt(int x,int y,int root)
{
while(find(x)!=root)
{
belong[x]=belong[match[x]]=root;
link[x]=y;
if(type[match[x]]!=1){type[match[x]]=1,Q.push(match[x]);}
y=match[x];x=link[y];
}
}
int trymatch(int now)
{
int x,y,temp;
while(!Q.empty())Q.pop();
for(int i=1;i<=n;i++)belong[i]=i,link[i]=type[i]=0;
Q.push(now),type[now]=1;
while(!Q.empty())
{
x=Q.front();Q.pop();
for(int i=pre[x];i;i=next[i])
{
y=to[i];
if(find(x)==find(y))continue;
if(!match[y])
{
link[y]=x;
for(int p1=y,p2=x,temp;p2;p2=link[p1])//这里少打了一个temp就调了好久orz
{
temp=match[p2];match[p2]=p1,match[p1]=p2;p1=temp;
}
return 1;
}
else if(type[y]==0)
{
type[y]=2,type[match[y]]=1,link[y]=x;
Q.push(match[y]);
}
else if(type[y]==1)
{
int root=LCA(x,y);
cnnt(x,y,root);
cnnt(y,x,root);
}
}
}
return 0;
}
int main()
{
n=RD(),m=RD();
for(int i=1;i<=m;i++)addedge(RD(),RD());
for(int i=1;i<=n;i++)
if(!match[i])ans+=trymatch(i);
printf("%d\n",ans);
for(int i=1;i<=n;i++)printf("%d ",match[i]);
return 0;
}