KM——二分图带权最大匹配

定义:完备匹配:两个集合顶点数都为N,且有N条边被匹配<每个点都匹配>。形象地理解:有n男n女,每个人都可以找到自己心仪的对象。

特点:只适用于完备匹配(两个集合顶点数都为N,且有N条边被匹配<每个点都匹配>)

定义:

  · 设二分图两个顶点集合为{A},{B}

  · 顶标:给每个顶点赋值,全称顶点标记值

    设集合{A}顶标为la[i],{B}顶标为lb[i],满足对于任何一条边W,两个顶点的顶标和>=边的权值(la[i] + lb[j] >= W(i , j) )

  · 交错树:考虑匈牙利算法,若寻找增广路失败,那一条路径即为“交错树”。显然,根据匈牙利算法,第(1,3,5,……)条边都为非匹配边,并且由子集{A}的顶点出发向子集{B}的顶点;第(2,4,6,……)条边都为已匹配边,并且由并且由子集{B}的顶点出发向子集{A}的顶点。并且这条路径起始点在子集{A},终点也在子集{A}。

  · 相等子图:设二分图两个顶点集合为{A},{B},由所有边满足W(ai,bj) = la[ai] + lb[bj]构成的二分图可以理解为相等子图是不带权值的

证明——一旦存在相等子图的完备匹配(不带权的),此匹配必然是二分图带权最大完备匹配!

  证明:

  一旦相等子图存在完备匹配,考虑其所有匹配边的权值和(虽然求相等子图完备匹配时不带权值,但最终还是要回归到原来的带权匹配,这里指的是边的原权值),为∑(i from 1 to n)la[i]+lb[i](为什么?) 而我们又知道对于任意一条边W,la[i] + lb[j] >= W(i , j)。因此原二分图的完备匹配(注意:n条边,涵盖所有2n个顶点)的n条边的权值之和不可能大于相等子图的完备匹配的权值之和!故此相等子图的完备匹配即为原二分图带权最大匹配!

  证毕。


  我们可以发现上述证明其实就是将问题转化为:如何求出适当的顶标值,使得相等子图拥有完备匹配。而相等子图的完备匹配(不带权!)可以用dfs求增广路解决(就是匈牙利算法的dfs部分)!

  

  下面我们来探讨如何给每个顶点求出适当的顶标值。

  我们可以考虑开始赋以每个顶点一个初值,比如lb[i] = 0, la[i] = max(W(ai,?)),这样,对于任意一条边,都满足la[i] + lb[j] >= W(i,j)。

  接下来,对{A}的每个顶点寻找它的“配偶”。

原文地址:https://www.cnblogs.com/StephenCurry30/p/10582035.html

时间: 2024-10-11 21:25:07

KM——二分图带权最大匹配的相关文章

二分图带权匹配(推箱子问题的思考)

转载请附上原文链接: http://blog.csdn.net/u013351484/article/details/51598270 二分图带权匹配(也叫二分图最优(最佳)匹配,Kuhn-Munkres 算法) 预备知识:二分图最大匹配,二分图完备(完美)匹配 二分图带权匹配,可以把它看作集合 X 的每个顶点到集合 Y 的每个顶点均有边的二分图(设权重均为正数,则原来分别在集合 X 与集合 Y 中没边的顶点 xi,yi 就可以添加一条权重为 0 的边,即 w[xi,yi] = 0):这样的二分

hdu 2255 二分图带权匹配 模板题

模板+注解在 http://blog.csdn.net/u011026968/article/details/38276945 hdu 2255 代码: //KM×î´ó×îСƥÅä #include <cstdio> #include <cstring> #include <algorithm> #include <iostream> using namespace std; #define INF 0x0fffffff const int MAXN

Ants 二分图带权最小匹配

Ants Solution: 此题最重要的是转化题意! 直接上图(图中红色才是正确方案): 这是一种很简单的情况,但是却告诉了我们很重要的信息. 仔细观察,可以发现,似乎最优方案的两两间连的边,距离值和最小! 那么,找一组连边方案,使得两两距离值和最小必然是最优方案. 为什么会这样呢, 其实是因为只要有相交的边,就会构成类似上图的'X'型, 那么就必定会存在两个三角形,相交的边一起构成两个三角形中的两边,必然大于其对应的第三边! 因而,我们只要选则第三边,就能保证不交,与此同时,选出来的边距离值

hdu 1569 &amp;1565 (二分图带权最大独立集 - 最小割应用)

要选出一些点,这些点之间没有相邻边且要求权值之和最大,求这个权值 分析:二分图带权最大独立集. 用最大流最小割定理求解.其建图思路是:将所有格点编号,奇数视作X部,偶数视作Y部,建立源点S和汇点T, S向X部的点建边,Y部向T建边,容量为该点权值. 相邻的一对点(肯定是一奇一偶),由X中的点向Y中的点建边,容量为正无穷. 最后跑出最大流,|带权最大独立集| = |点权之和| - |最小割| = |点权之和| - |最大流| #include<iostream> #include<cstr

二分图带权匹配

带权匹配是指在最大匹配的基础上,使匹配边的边权和最大.一般有两种写法,一个是KM算法(只针对可以完备匹配的二分图),一个是费用流. KM算法在稠密图上比费用流更优秀一些,不过应用范围太小,所以还是鼓励大家用费用流.当然啦,作为一种算法KM也是我们需要了解的(况且我不会网络流??). KM算法有个流程: 1.存图 2.用贪心算法初始化标杆 3.运用匈牙利算法找到完备匹配 4.如果找不到完备匹配,通过修改标杆增加一些边 5.重复做3和4两个步骤,直到找到完备匹配. 其他的话,我表述的也不是很好,理解

poj 2195 二分图带权匹配

题意:有一个矩阵,某些格有人,某些格有房子,每个人可以上下左右移动,问给每个人进一个房子,所有人需要走的距离之和最小是多少. 貌似以前见过很多这样类似的题,都不会,现在知道是用KM算法做了 KM算法目前还没弄懂,先套模板做 Sample Input 2 2 .m H. 5 5 HH..m ..... ..... ..... mm..H 7 8 ...H.... ...H.... ...H.... mmmHmmmm ...H.... ...H.... ...H.... 0 0 Sample Out

二分图带权匹配-Kuhn-Munkres算法模板 [二分图带权匹配]

尴尬...理解不太好T T 1 #include<cstdio> 2 #include<cstring> 3 #include<iostream> 4 #include<algorithm> 5 using namespace std; 6 #define inf 0x3f3f3f3f 7 8 const int maxn=1005; 9 10 int n; 11 //标杆序号 12 int lx[maxn],ly[maxn]; 13 //是否被搜索过 14

二分图的最大匹配、带权最大匹配

给定一个二分图G,M为G边集的一个子集,如果M满足当中的任意两条边都不依附于同一个顶点,则称M是一个匹配. Reference:google上搜"ByVoid 二分图"(被墙了T^T) 计算二分图的最大匹配:匈牙利算法 模板: #include <stdio.h> #include <string.h> #define MAX 102 long n,n1,match; long adjl[MAX][MAX]; long mat[MAX]; bool used[M

ural 1076 KM求最小权匹配

贴模板~ KM算法引进了顶标函数,不断缩小这个顶标来让相等子图的可能范围扩大 #include<iostream> #include<cstring> //KM 复杂度O^3 using namespace std; const int N=200; int lx[N],ly[N];//顶标函数 int w[N][N];//图 bool vix[N],viy[N]; int linky[N];// int lack;//每次顶标函数扩大的增量 int n,m; bool find(