二分图匹配

二分图匹配

一个图可以分成两个部分,其中同一部分的点没有边,不同部分有边相连,求解最多能匹配多少点。

采用匈牙利算法求解:

对于每个点的一种匹配

1.匹配点未选择,将此点与匹配点匹配。

2.匹配点已与其它点a匹配:将a进行匹配,即重复1,2步骤。

若满足以上条件之一,则此点可匹配。

#include<bits/stdc++.h>
using namespace std;
const int maxe=1000005;
const int maxn=2005;
int a,b,n,m,e,tot;
int las[maxe],nex[maxe];
int vis[maxn],lnk[maxn],matched[maxn];
int read()
{
	int ch=0,x=0;while(ch=getchar(),ch<'0'||ch>'9');
	while(x=x*10+ch-48,ch=getchar(),ch>='0'&&ch<='9');
	return x;
}
void add(int x,int y){nex[++tot]=y;las[tot]=lnk[x];lnk[x]=tot;}
int find(int x)
{
	for(int k=lnk[x];k;k=las[k])
	{
		if(vis[nex[k]])continue;
		vis[nex[k]]=1;
		if(!matched[nex[k]]){matched[nex[k]]=x;return 1;}
		if(find(matched[nex[k]])){matched[nex[k]]=x;return 1;}
	}
}
void maxcomplete()
{
	int cnt=0;
	for(int i=1;i<=n;i++)
	{
		memset(vis,0,sizeof(vis));
		if(find(i))cnt++;
	}
	printf("%d",cnt);
}
int main()
{
	n=read();m=read();e=read();
	for(int i=1;i<=e;i++)
	{
		a=read();b=read();
		if(b>m)continue;
		add(a,b+n);
	}
	maxcomplete();
	return 0;
}
posted @ 2019-04-07 20:43  DavidJing  阅读(153)  评论(0编辑  收藏  举报