匈牙利算法(二分图匹配)模板

在复杂度允许的范围下可以用最大流代替匈牙利算法

bool map[maxn][maxm];	//map[x][y]=true表示点x和点y有边相连 
bool road[maxm];	 	//road[i]记录点i是否已在当前增广路中,防止死循环 
int link[maxm];			//link[i]记录增广路上与i相连的前一个节点的编号,即记录已求出的匹配,简单的说link[i]用于记录匹配集合中的边 
bool find(int v)		//find查找从v点出发是否有可增广路 
{
	int i;
	for(i=1; i<=m; i++)	//可用邻接链表,枚举在下半部分图中与v点相关联的点 
	{
		if(map[v][i]&&(!road[i]))	//如果该点不在增广路上 
		{
			road[i]=true;			//把i标记为已讨论,防止死循环 
			if(link[i]==0||find(link[i]))	//i是未匹配点(未盖点)或者从i的匹配点出发有可增广路 
			{
				link[i]=v;					//修改与i匹配的点为v 
				return true;				//则从v出发可找到增广路,返回true 
			}
		}
	}
	return false;	//如果从v出发没有增广路,返回false 
}
int main()
{
	//read the graph into array map[]	//首先读入图结构到map数组中 
	for(i=1; i<=n; i++)					//依次从上半部图的点出发,寻找增广路 
	{
		for(j=1; j<=m; j++)road[j]=false;
		if(find(i))tot++;				//每找到一条增广路,匹配数加1(最多n个匹配) 
	}
	printf("%d", tot);					//输出最大匹配数 
}



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值