匈牙利算法小讲

又名:匈牙利算法的封建

(bushi

匈牙利增广路算法,简称匈牙利算法

原理:反转一条交错路径之后匹配边数+1,找增广路

我们先来假设一个通篇都要用到的前提

现在有 n 名男生, m 名女生。其中有 k 对男女互有好感,保证不出现gay或百合

一人不一定只有一个人与之配对(即一个女生可以与多个男生互有好感,反之亦然)。

若一对互有好感,那么我们作为中介可以让两人原地结婚。但是不可重婚,那是犯罪

好了,请问我们最多能撮合出最多几对夫妻呢?

那么显然,我们应用二分图的知识解决问题,方法如下图

显然,假定男生们为主动方,如果他能找到的女生中有暂时没结婚的,就跟她结婚

但是我们会遇到一个问题:你得到的是否是最多对

下图就是一个例子:

这时,我们所讲的匈牙利算法就派上用场了!

让我们以此图为例

我们首先让 15 结婚,再给2介绍对象。

但我们经过查询发现: 2 有一心仪对象 5 结了婚了!

我们再看一看 1 ,发现他其实还可以和 6 结婚且 6 未婚。

邪恶的匈牙利算法便强制让 15 离婚以此给 2 找老婆!

太邪恶了!赤裸裸的包办婚姻!!!

再看 3 ,却不曾想 3 有一心仪对象 6 结了婚了!

我们再看一看 1 ,发现他其实和 5 还可以破镜重圆且 2 还可以和 7 结婚。

邪恶的匈牙利算法便又动了手脚:

15结婚,27结婚,36结婚

接下来到 4 了。很幸运,他可以直接和 8 结婚。

拆散婚姻什么的已经无所谓了,因为不再有姻缘,值得去拆了。——匈牙利算法

好了你已经掌握了匈牙利算法是个什么东西了。

接下来,也是最后一部分,就是喜闻乐见的上代码时间了:

(:代码参考了我校一个老二刺猿学长 shadowice1984,即 tbl 的 )

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;

const int N=510;
int n,m,e;
int mp[N][N],match[N];
bool book[N];
  
bool dfs(int x){
    for(int i=1;i<=m;i++){
	if(book[i]||!mp[x][i])
	    continue;
	book[i]=true;
	if(match[i]==0||dfs(match[i])){
	    match[i]=x;
	    return true;
	}
    }
    return false;
}
int main(){
	scanf("%d%d%d",&n,&m,&e);
	for(int i=1;i<=e;i++){
		int j;int k;
		scanf("%d%d",&j,&k);
		mp[j][k]=1;
	}
	int ans=0;
	for(int i=1;i<=n;i++){
		for(int j=1;j<=m;j++)
			book[j]=false;
		ans+=dfs(i);
	}
	printf("%d",ans);
	return 0;
}
posted @   BFNewdawn  阅读(80)  评论(0编辑  收藏  举报
编辑推荐:
· 电商平台中订单未支付过期如何实现自动关单?
· 用 .NET NativeAOT 构建完全 distroless 的静态链接应用
· 为什么构造函数需要尽可能的简单
· 探秘 MySQL 索引底层原理,解锁数据库优化的关键密码(下)
· 大模型 Token 究竟是啥:图解大模型Token
阅读排行:
· 一文彻底搞懂 MCP:AI 大模型的标准化工具箱
· 面试官:如果某个业务量突然提升100倍QPS你会怎么做?
· 短信接口被刷爆:我用Nginx临时止血
· .NET 平台上的开源模型训练与推理进展
· 聊聊智商税:AI知识库
点击右上角即可分享
微信分享提示