最大匹配问题——匈牙利算法

二分图指,具有L,R两个点集合,每个集合内没有连边,集合之间的点有连边。
二分图最大匹配问题是指,找到一个确定边最多。即选择的边最多,且任何两边都没有公共点。若两个集合内的点都被匹配上,成为完美匹配。
这类问题可以用网络流,但是匈牙利算法更加简洁。
这就是一个二分图模型,设左边深蓝色的点为L集,右边粉红色的点为R集合,黑色的边为可连边。
在这里插入图片描述
(1):找L1的首可连边,再找L2的首可连边,这两个R集的R1,R2点都是未盖点(称未匹配点为未盖点)。得到这个图:
在这里插入图片描述
(2)我们为L集第三点找确定边,我们先找首可连边(即这个点连边的最上面的一条边)L3-R1,我们发现这个点已经匹配,则我们强制将这个匹配给L3。R1的原匹配点L1需要重新匹配,L1的最先可连边且未匹配边的点为L1-R2,我们发现R2已经被L2匹配了,我们强制L1匹配R2。然后我们需要为R2的原可连边找新的匹配点,L2的最先可连边且未匹配边为L2-R3,发现R3为未匹配点,那么L2匹配R3结束。
从上面的图中可以看到,这次我们连边的路径是先从未匹配点开始,以此经过未匹配边,匹配边,未匹配边,匹配边,未匹配边,最后到一个未匹配点。 这就是匈牙利算法的核心
在这里插入图片描述

(3)为L4确定边,还是上面黑字的思路进行匹配。
走到5的时候发现,L4-R1已经是匹配边,继续一直走下去会死循环,或者说在代码中,会实现这一步返回false,然后L2换一条边出发。
在这里插入图片描述
回溯到L2,选择L2-R4,继续匹配
在这里插入图片描述
最终得到一个完美匹配图
在这里插入图片描述
模板代码:

int used[maxn],g[maxn][maxn],book[maxn];
int Ln,Rn;
bool find(int x){
	for(int i=1;i<=Rn;i++){
		if(used[i]==0&&g[x][i]){
			used[i]=1;
			if(book[i]==0||find(book[i])){
				book[i]=x;
				return true;
			}
		}
	}
	return false;
}
for(int i=1;i<=Ln;i++){
	memset(used,0,sizeof used);
	if(find(i)==false)
		flag=0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值