2019/7/22 匈牙利算法,KM算法

    这几天知识点量太大,一时间不易吸收。先占个坑,慢慢填

匈牙利算法

分享一位博主Dark_Scope的思路,简单易懂还有趣,虽然是初学,也马马虎虎懂了个大概    https://blog.csdn.net/dark_scope/article/details/8880547

#define maxn 100000
int n,m;//n个男生 m个女生  二分图:男生在左女生在右 
bool line[maxn][maxn]; //两者之间相互喜欢
bool used[maxn];//记录是否被标记过
int girl[maxn];//记录右边女生所对应的男生的编号 
bool find(int x) {
	int i,j;
	for(j=1; j<=m; j++)	{
		if(line[x][j]==true&&used[j]=false) {//如果相互喜欢且没有
		//被标记过(标记指这次查找曾试图改变过此人的归属问题,
		//但没有成功,已经被标记了,也就不用费功夫了) 
			used[j] = 1; //被标记 
			if(girl[j]==0 || find(girl[j])) { //短路 
				girl[j]=x;
				return true;
			} 
		}
	} 
	return false;
}

int main() {
	int ans=0; //最大匹配个数 
	for(int i=1;i<=n;i++) { //二分图左边依次遍历 
		memset(used,0,sizeof(used)); //每次都要清空标记,方便“腾”人 
		ans += find(i); 
	}
} 

 

KM算法

      主要用来解决带权二分图的匹配问题,在保证最大匹配的前提使得权值和最大。

步骤:

1.分别为左右点设置标杆,左边初始为最大值,右边设置为0

2. 对于左边的点,首先考虑权值最大的边与之相连,连接的前提是左右点的标杆值和等于权值。

3.存在矛盾就减少增广路上左边的权值同时增加增广路右边的权值

4.重复以上步骤直到匹配结束。

参见博主hehedad的思路,写的同样很好嗷。   https://blog.csdn.net/chenshibo17/article/details/79933191

 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值