匈牙利算法(二分图匹配问题)

匈牙利算法(二分图匹配问题)

问题链接(杭电2063题):http://acm.hdu.edu.cn/showproblem.php?pid=2063
参考博客:https://blog.csdn.net/cillyb/article/details/55511666
找伴侣是个递归的过程,最最关键的字就是“腾”字
其原则大概是:有机会上,没机会创造机会也要上

#include<iostream>
#include<cstring>
using namespace std;
/*匈牙利算法,二分图匹配,杭电2063题*/
int k,m,n;  //k为组合数,m为左侧数,n为右侧点数
bool vis[520];   //这个右侧点是否被找过 
int line[520][520];  
//line表示左侧女生和右侧男生是否相互喜欢
int peidui[520];
//peidui表示右侧男生匹配到的左侧女生的点 
bool find(int x)  //匈牙利算法是递归的 
{
	for(int i=1;i<=n;i++)  //遍历图的左侧所有男生 
	{
		if(line[x][i]==1&&!vis[i])  //如果该右侧男生没有被访问过,并且左侧x喜欢右侧i 
		{
			vis[i]=true;  //设置该右侧男生被访问过 
			if(peidui[i]==0||find(peidui[i]))  //如果右侧男生没有被配对,或者右侧的原配可以寻找到新的配对 
			{
				peidui[i]=x;  //则该右侧点匹配到该左侧点 
				return true;  //返回结果真 
			}
		}
	} 
	return false;  //否则返回结果假 
}
int main()
{
	int ans;  //最大配对数 
	int g,b;  //g为图的左侧,b为右侧 
	while(cin>>k&&k)  //输入组合数 
	{
		cin>>m>>n;  //输入图左侧点的个数、图右侧点的个数 
		memset(line,0,sizeof(line));  //初始化邻接矩阵 
		memset(peidui,0,sizeof(peidui));  //初始化访问数组 
		for(int i=0;i<k;i++)
		{
			cin>>g>>b;  //输入左侧点、右侧点 
                        line[g][b]=1;	//g左侧喜欢b右侧,设置为有边 
		}
		ans=0;
		for(int i=1;i<=m;i++)  //遍历所有左侧点 
		{
			memset(vis,false,sizeof(vis));  //每次都需要初始化访问数组 
			if(find(i))    ans++;  //如果配对成功,结果自增 
		}
		cout<<ans<<endl; //输出结果 
	}
} 

猜你喜欢

转载自blog.csdn.net/qq_39905917/article/details/84671569