KM算法(二分图完美匹配)

前言

其实这是一个很玄学的算法,我也不是很懂。但是慢慢地写,就慢慢地懂了。


例子

我们先看到这样一个例子:
现有n个男生和n个女生,每一个女生对于一个男生都有一个期望值。现在想知道期望值最大是多少。

算法

那么显然,我们需要一种算法来完成这个任务,KM腾空出世!

在此之前,我们需要了解一些东西:

前置知识

期望值:女生连的边中边权最大的值,称之为女生的期望值

l(x)+l(y)>=w(i,j)

当l(x)+l(y)=w(i,j)时,是M图的完美匹配!

过程

原则

  • 能换就换(思想很像匈牙利求二分图最大匹配)

做法

  1. 对于每一个妹子,选择她最喜欢的男生
  2. 如果无法达到以上要求,前往4
  3. 如果可以,递归修改她人男友.前往1
  4. 所有访问过的女生值域减去
  5. 访问过的男生值域加上

代码实现

复杂度及优化

以上代码的复杂度为O(n^4)

有一些优化可以使代码复杂度降为O(n^3),由EK提出

显然,每一次修改,我们都不停地在计算l(x)+l(y)-w(x,y),不妨设一个变量slack表示l(x)+l(y)-w(x,y),那么显然,我们每一次查询就从O(n^2)变成了O(n),每一次修改的复杂度为O(1)

例题

时间: 2024-10-12 03:05:10

KM算法(二分图完美匹配)的相关文章

UVA 1045 - The Great Wall Game(二分图完美匹配)

UVA 1045 - The Great Wall Game 题目链接 题意:给定一个n*n的棋盘,有n个棋子在上面,现在要移动棋子,每一步代价是1,现在要把棋子移动到一行,一列,或者在主副对角线上,问最小代价 思路:二分图完美匹配,枚举每种情况,建边,边权为曼哈顿距离,然后km算法做完美匹配算出值即可,由于要求最小值所以边权传负数,这样做出来的值的负就是答案 代码: #include <cstdio> #include <cstring> #include <cmath&g

UVA 11383 - Golden Tiger Claw(二分图完美匹配扩展)

UVA 11383 - Golden Tiger Claw 题目链接 题意:给定每列和每行的和,给定一个矩阵,要求每个格子(x, y)的值小于row(i) + col(j),求一种方案,并且所有行列之和的和最小 思路:A二分图完美匹配的扩展,行列建二分图,权值为矩阵相应位置的值,做一次KM算法后,所有顶标之和就是最小的 代码: #include <cstdio> #include <cstring> #include <cmath> #include <algor

UVA 10888 - Warehouse(二分图完美匹配)

UVA 10888 - Warehouse option=com_onlinejudge&Itemid=8&page=show_problem&category=562&problem=1829&mosmsg=Submission+received+with+ID+14222079" target="_blank" style="">题目链接 题意:就是推箱子游戏,问最少要几步 思路:每一个箱子和目标位置建边.

UVA 1411 - Ants(二分图完美匹配)

UVA 1411 - Ants 题目链接 题意:给定一些黑点白点,要求一个黑点连接一个白点,而且全部线段都不相交 思路:二分图完美匹配,权值存负的欧几里得距离,这种话,相交肯定比不相交权值小,所以做一次完美匹配就能够了 代码: #include <cstdio> #include <cstring> #include <cmath> #include <algorithm> using namespace std; const int MAXNODE = 1

POJ 1904 King&#39;s Quest强连通分量+二分图完美匹配

题目描述: Description Once upon a time there lived a king and he had N sons. And there were N beautiful girls in the kingdom and the king knew about each of his sons which of those girls he did like. The sons of the king were young and light-headed, so i

KM算法【带权二分图完美匹配】

先orz litble--KM算法 为什么要用KM算法 因为有的题丧心病狂卡费用流 KM算法相比于费用流来说,具有更高的效率. 算法流程 我们给每一个点设一个期望值[可行顶标] 对于左边的点来说,就是期望能匹配到多大权值的右边的点 对于右边的点来说,就是期望能在左边的点的期望之上还能产生多少贡献 两个点能匹配,当且仅当它们的期望值之和为这条边的权值 一开始初始化所有左点的期望是其出边的最大值,因为最理想情况下当然是每个点都匹配自己能匹配最大的那个 右点期望为0 然后我们逐个匹配,当一个点匹配失败

km算法(二分图最大权匹配)学习

啦啦啦! KM算法是通过给每个顶点一个标号(叫做顶标)来把求最大权匹配的问题转 化为求完备匹配的问题的.设顶点Xi的顶标为A[i],顶点Yi的顶标为B[i],顶点Xi与Yj之间的边权为w[i,j].在算法执行过程中的任一时刻,对于任一条边(i,j), A[i]+B[j]>=w[i,j]始终成立. KM算法的正确性基于以下定理: *  若由二分图中所有满足A[i]+B[j]=w[i,j]的边(i,j)构成的子图(称做相等子图)有完备匹配,那么这个完备匹配就是二分图的最大权匹配. * 这个定理是显然

HDU 2255 奔小康赚大钱(KM算法求完备匹配)

Problem Description: 传说在遥远的地方有一个非常富裕的村落,有一天,村长决定进行制度改革:重新分配房子.这可是一件大事,关系到人民的住房问题啊.村里共有n间房间,刚好有n家老百姓,考虑到每家都要有房住(如果有老百姓没房子住的话,容易引起不安定因素),每家必须分配到一间房子且只能得到一间房子.另一方面,村长和另外的村领导希望得到最大的效益,这样村里的机构才会有钱.由于老百姓都比较富裕,他们都能对每一间房子在他们的经济范围内出一定的价格,比如有3间房子,一家老百姓可以对第一间出1

POJ - 1486 Sorting Slides 二分图 完美匹配

题目大意:有n张透明的矩形纸张散乱在桌面上,每张纸张上面都有一个数字. 现在给出每个矩形的左下角和右上角坐标和每个数字所在的位置,问能否找出每个矩形唯一的对应数字 解题思路:分析该题可得到,二分图匹配的结果肯定是完美匹配,匹配的结果肯定为n. 接着就要判断每个点是否唯一匹配了 判断能否唯一匹配,就要在完美匹配的情况下,删除该点的那条匹配,如果还能再找出一个完美匹配,那么就表示该点表示不唯一 #include<cstdio> #include<vector> #include<