匈牙利算法

参考了趣写算法这篇文章来理解匈牙利算法,但是还没有吃透找增广路径算法原理,不能合理带入算法思想,嘤。

匈牙利算法

用增广路求最大匹配(称作匈牙利算法,匈牙利数学家Edmonds于1965年提出) 
算法轮廓:

  1. 置M为空
  2. 找出一条增广路径P,通过取反操作获得更大的匹配M’代替M
  3. 重复2操作直到找不出增广路径为止

找增广路径的算法

我们采用DFS的办法找一条增广路径: 
从X部一个未匹配的顶点u开始,找一个未访问的邻接点v(v一定是Y部顶点)。对于v,分两种情况:

  1. 如果v未匹配,则已经找到一条增广路
  2. 如果v已经匹配,则取出v的匹配顶点w(w一定是X部顶点),边(w,v)目前是匹配的,根据“取反”的想法,要将(w,v)改为未匹配,(u,v)设为匹配,能实现这一点的条件是看从w为起点能否找到一条增广路径P’。如果行,则u-v-P’就是一条以u为起点的增广路径。
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;
}

每次查询男生要初始化used数组

for (i=1;i<=n;i++)
{
	memset(used,0,sizeof(used));    //这个在每一步中清空
	if find(i) all+=1;
}

算法分析

算法的核心是找增广路径的过程DFS 
对于每个可以与u匹配的顶点v,假如它未被匹配,可以直接用v与u匹配; 
如果v已与顶点w匹配,那么只需调用dfs(w)来求证w是否可以与其它顶点匹配,如果dfs(w)返回true的话,仍可以使v与u匹配;如果dfs(w)返回false,则检查u的下一个邻接点……. 
在dfs时,要标记访问过的顶点(visit[j]=true),以防死循环和重复计算;每次在主过程中开始一次dfs前,所有的顶点都是未标记的。 
主过程只需对每个X部的顶点调用dfs,如果返回一次true,就对最大匹配数加一;一个简单的循环就求出了最大匹配的数目

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值