算法自学__匈牙利算法
创始人
2025-05-29 19:46:19

参考资料:

  • https://zhuanlan.zhihu.com/p/96229700

算法简介

匈牙利算法主要用求二分图的最大匹配最小覆盖

最大匹配问题

问题描述

一种形象的表述:把二分图中的一部分假设为男,另一部分为女,男生和女生之间有暧昧关系,求最大匹配就是求最多能促成多少对情侣。

算法思想

先到先得,能让则让。

代码

// 邻接矩阵存边
bool mat[maxn][maxn];
// vis[i]表示:i号女生是否已经配对
bool vis[maxn];
// p[i]表示:与i号女生配对的男生编号
int p[maxn];bool match(int i){for(int j=1;j<=n;j++){// 该女生未配对,且这对男女之间有暧昧关系if(!vis[j] && mat[i][j]){vis[j] = 1;/* match(p[j])表示让之前与i号女生配对的男生换匹配对象 */if(p[j]==0 || match(p[j])){p[j] = i;return true;}}}return false;
}int Hungarian(){int res = 0;for(int i=1;i<=n;i++){memset(vis, 0, sizeof(vis));// 统计匹配成功的男生数if(match(i)) res++;}return res;
}

例1 P1129 [ZJOI2007] 矩阵游戏

题目大意

给定一个由 01 构成的方阵,可以交换行和列,问能否通过交换操作使得方阵的主对角线上全为 1

思路

将矩阵转化为二分图,一部分代表各行,另一部分代表各列,如果方阵有 mat[i][j] == 1 ,则在行 i 和列 j 之间建立一条边。对这个二分图求最大匹配,如果匹配数恰好等于方阵的行列数 n ,则输出 Yes ,否则输出 No

代码

#include
using namespace std;const int maxn = 205;int T, n;
bool mat[maxn][maxn];
bool vis[maxn];
int p[maxn];bool match(int i){for(int j=1;j<=n;j++){if(!vis[j] && mat[i][j]){vis[j] = 1;if(p[j]==0 || match(p[j])){p[j] = i;return true;}}}return false;
}int Hungarian(){int res = 0;for(int i=1;i<=n;i++){memset(vis, 0, sizeof(vis));if(match(i)) res++;}return res;
}int main(){cin>>T;while(T--){cin>>n;memset(p, 0, sizeof(p));for(int i=1;i<=n;i++){for(int j=1;j<=n;j++){bool a;cin>>a;if(a) mat[i][j] = 1;else mat[i][j] = 0;}}if(Hungarian() == n) cout<<"Yes";else cout<<"No";cout<<'\n';} return 0;
}

最小覆盖问题

问题描述

找到最少的点,删掉所有包含这些点的边,可以删掉所有边。

算法思路

结论:最小覆盖的点数等于最大匹配数。

找到最小覆盖点集的方法:从左侧一个未匹配成功的点出发,走一趟匈牙利算法的流程(即紫色的箭头),所有左侧未经过的点,和右侧经过的点,即组成最小点覆盖。

例1 vijos1204 CoVH之柯南开锁

题目大意

给定一个由 01 构成的 n*m 的矩阵,每次操作可以一行或一列的 1 全部变成 0 。问最少经过多少次操作才能使矩阵全 0

思路

仿照矩阵游戏建立二分图,每次操作等价于删除所有包含该点的边,此时问题就转化成了求二分图的最小覆盖。

代码

略。

相关内容

热门资讯

云龙天池国家级自然保护区入选世... 转自:云南日报记者近日从云龙天池国家级自然保护区获悉,该保护区正式入选世界自然保护联盟绿色名录,成为...
芒果干里的“暖心账”​ 我 为 群 众 办 实 事我是楚雄彝族自治州楚雄市八角镇大麦地村委会泥期苴小组的鲁晓玲。天还没亮,新...
在亲戚借条上签名被判连带清偿责...   三湘都市报12月14日讯  欠钱逾期未还,双方公堂对簿,竟因借据上的“担保人”“连带担保人”起了...
学分能换“高级工”证书?湖南暂...   毕业就能拿到“高级工”的技能证书,实现“毕业即持证”,这是种什么样的体验?近日,安徽皖江工学院土...
长赣高铁湖南段首座隧道进洞施工     12月13日,位于浏阳市荷花街道和澄潭江镇的长赣高铁湖南段首座隧道——苏家庵隧道正式进洞。 ...