题意
一般图的最大匹配
题解
模板题啊
以前学过一次,但是没有学会。。
感受一下就好。。
代码还是很好写的
CODE:
#include<cstdio>
#include<algorithm>
#include<iostream>
#include<cstring>
#include<queue>
using namespace std;
const int N=505;
const int M=124755;
struct qq
{
int x,y,last;
}e[M*2];int num,last[N];
int n,m;
int f[N];
int fa[N];
int id[N];
int par[N];//父亲
int findfa (int x) {return fa[x]==x?fa[x]:fa[x]=findfa(fa[x]);}
queue<int> q;
int tim;
int vis[N];
void init (int x,int y)
{
num++;
e[num].x=x;e[num].y=y;
e[num].last=last[x];
last[x]=num;
}
int lca (int x,int y)
{
tim++;
while (vis[x]!=tim)
{
if (x!=0)
{
x=findfa(x);
if (vis[x]==tim) return x;
vis[x]=tim;
x=findfa(par[f[x]]);
}
swap(x,y);
}
return x;
}
void change (int x,int y,int k)
{
int z;
while (findfa(x)!=k)
{
par[x]=y;z=f[x];
id[z]=0;q.push(z);
if (findfa(z)==z) fa[findfa(z)]=k;
if (findfa(x)==x) fa[findfa(x)]=k;
y=z;x=par[y];
}
}
void bfs (int xx)
{
for (int u=1;u<=n;u++) {id[u]=-1;fa[u]=u;}
while (!q.empty()) q.pop();
q.push(xx);id[xx]=0;
while (!q.empty())
{
int x=q.front();q.pop();
for (int u=last[x];u!=-1;u=e[u].last)
{
int y=e[u].y;
if (f[y]==0&&y!=xx)//找到匹配了
{
par[y]=x;
int now=y,last,t;
while (now!=0)
{
t=par[now];last=f[t];
f[t]=now;f[now]=t;
now=last;
}
return ;
}
if (id[y]==-1)//尝试增广
{
id[y]=1;par[y]=x;
id[f[y]]=0;q.push(f[y]);
}
else if (id[y]==0&&findfa(x)!=findfa(y))//一个奇环
{
int g=lca(x,y);
change(x,y,g);change(y,x,g);
}
}
}
}
int main()
{
num=0;memset(last,-1,sizeof(last));
scanf("%d%d",&n,&m);
for (int u=1;u<=m;u++)
{
int x,y;
scanf("%d%d",&x,&y);
init(x,y);init(y,x);
}
for (int u=1;u<=n;u++)
if (f[u]==0)
bfs(u);
int ans=0;
for (int u=1;u<=n;u++)
if (f[u]!=0)
ans++;
printf("%d\n",ans/2);
for (int u=1;u<=n;u++) printf("%d ",f[u]);
return 0;
}