部分定义

  • 传递闭包

    一个图。如果图 G G G中点i" role="presentation">iii到点 j j j存在通路,那么在传递闭包中有边i−>j" role="presentation">i−>ji−>ji->j

  • 二分图

    一个图 G G G,可以将其所有点分成x,y" role="presentation">x,yx,yx,y两个点集,同时所有边满足他的两个端点分别落在 x,y x , y x,y上,而不会落在同一个集合里。

  • 匹配

    实际为原图 G G G一个边集,G" role="presentation">GGG中任意点作边的端点至多一次。
    通俗一点的说法:将图中部分或所有点一对一对通过一条边配起来
    最大匹配:边集中边数最多的一个匹配。
    .
    举例来说:如下图所示,如果在某一对男孩和女孩之间存在相连的边,就意味着他们彼此喜欢。是否可能让所有男孩和女孩两两配对,使得每对儿都互相喜欢呢?图论中,这就是完美匹配问题。如果换一个说法:最多有多少互相喜欢的男孩/女孩可以配对儿?这就是最大匹配问题。

  • 增广路

    在图 G G G与图G" role="presentation">GGG的一个匹配边集 M M M的前提下
    一条由未匹配顶点x" role="presentation">xxx到 y y y的路径。
    这条路径上一条是已匹配边,一条是未匹配边,如此相交错(交替路),
    其中第一条和最后一条边一定不是匹配边 (因为x,y" role="presentation">x,yx,yx,y未匹配)。
    因为增广路主要应用于匈牙利算法中,用于求二分图最大匹配,所以我们一般在二分图基础上讨论他。

增广路的性质:

1 有奇数条边。

匹配边与未匹配边交替出现且首尾都为未匹配边。

2 路径上的点一定是一个在左半边,一个在右半边,交替出现。

由二分图性质得,因为二分图同一边的点之间没有边相连。

3 路径上的所有第奇数条边都不在原匹配中,所有第偶数条边都出现在原匹配中。

同上

4 增广路径的取反可扩大匹配

增广路径的取反:
把增广路径上的所有未匹配边加入到原匹配中去,并把增广路径中的所有匹配边边从原匹配中删除。

显然的这条路径上的一个点可以和他相邻的两个点匹配。
所以我们调整增广路上的端点的匹配顺序,将空出的 x,y x , y x,y匹配
这样变动依旧每个顶点只会出现一次,且边数增加了一条

二分图最大匹配_匈牙利算法

既然我们知道增广路的取反可以增加匹配边数,那我们就不断的去找增广路去取反他,直到没有为止。当找不到增广路时,那么当前匹配就是最大匹配
(增广路的推论 M为G的最大匹配当且仅当不存在M的增广路径。),

证明思路大概是这样的: 如果从一个点A出发,没有找到增广路径,那么无论再从别的点出发找到多少增广路径来改变现在的匹配,从A出发都永远找不到增广路径。

匈牙利算法正是这么做的。

一个老司机写的教程:老司机开车就是稳!

伪代码

bool find(int x){  for (与x相连且当前没有找过增广路的点i) {标记找过;if (i已经匹配过) {找与i匹配的点是否有增广路,//if find(link(i)) 这里就相当于交替路了如果是:返回true表示有增广路;} else  {可做增广路末端点,返回true;}}return false;
}
for (i=1;i<=n;i++) //每个左边点
{   memset(used,0,sizeof(used)); if find(i) all+=1; //找增广路
}

其实理解上来说我们可以想成一个不断让的过程(贪心),其原理自己清楚就好。

时间复杂度分析

枚举每个点的增广路为n;
最坏情况枚举所有边m;
虽然最坏O(nm)的复杂度比较难看,但是匈牙利算法在实际应用中平均复杂度还是比较优秀的,且思维难度不大,代码复杂度低,是比较可取的一种二分图最大匹配算法。
其他算法有网络流,还有分层优化的匈牙利,以后再看看吧。

应用

(1)二分图的最小顶点覆盖

最小顶点覆盖要求用最少的点(X或Y中都行),让每条边都至少和其中一个点关联。

Knoig定理:二分图的最小顶点覆盖数等于二分图的最大匹配数。
简单理解:建出求二分图最大匹配的网络,中间的边是inf.
首先最大匹配 = 最大流,//TODO

(2)有向无环图(DAG)的最小路径覆盖

用尽量少的不相交简单路径覆盖有向无环图G的所有顶点,这就是DAG图的最小路径覆盖问题。
结论:DAG图的最小路径覆盖数 = 节点数(n)- 新图最大匹配数(m)
新图为把每一个顶点x分为入点和出点x,x’两个集合,对于由x->y的边,在新图中连x’->y,这样会得到一个二分图
粗略证明1:设最大匹配数为m,总顶点数为n。为了使边数最少,又因为一条边最多能干掉两个点,所以尽量用边干掉两个点
也就是取有匹配的那些边,当然这些边是越多越好,那就是最大匹配了,所以先用最大 匹配数目的边干掉大多数点.
剩下的解决没有被匹配的点,就只能一条边干掉一个点了,设这些数目为a
显然,2m+a=n,而最小边覆盖=m+a,
所以最小边覆盖=(2m+a)-m=n-m

(3)二分图的最大独立集

最大独立集问题: 在N个点的图G中选出m个点,使这m个点两两之间没有边.求m最大值
结论:二分图的最大独立集数 =节点数(n)— 最大匹配数(m)
最大独立集=最小覆盖。 这个显然。


  1. 引自http://blog.csdn.net/jackyguo1992/article/details/8184359 ↩

二分图最大匹配与其应用相关推荐

  1. 【网络流24题】解题报告:A、飞行员配对方案问题(最大流求二分图最大匹配)

    A.飞行员配对方案问题 (二分图最大匹配)(最大流)[提高+/省选- ] 题目链接 [问题分析] 二分图最大匹配问题. [建模方法] 在二分图的基础上增加源S和汇T. 1.S向X集合中每个顶点连一条容 ...

  2. 【模板】匈牙利算法 二分图最大匹配题模板

    [任务] 给定一个二分图,用匈牙利算法求这个二分图的最大匹配数. [说明] 求最大匹配,那么我们希望每一个在左边的点都尽量找到右边的一个点和它匹配. 我们一次枚举左边的点x的所有出边指向的点y, 若y ...

  3. 51nod 2006 飞行员配对(二分图最大匹配) 裸匈牙利算法 求二分图最大匹配题

    题目: 题目已经说了是最大二分匹配题, 查了一下最大二分匹配题有两种解法, 匈牙利算法和网络流. 看了一下觉得匈牙利算法更好理解, 然后我照着小红书模板打了一遍就过了. 匈牙利算法:先试着把没用过的左 ...

  4. 2021牛客多校3 - Minimum grid(二分图最大匹配-最大流)

    题目链接:点击查看 题目大意:给出一个 n∗nn*nn∗n 的棋盘,其中有 mmm 个位置是需要填数字的位置,每个位置需要填 [0,k][0,k][0,k] 的数字中的其中一个,可以重复,现在给出每一 ...

  5. HDU - 1054 Strategic Game(最小点覆盖-二分图最大匹配)

    题目链接:点击查看 题目大意:给出一棵树,现在要在节点上放置士兵,每个士兵可以监视与其所在的节点直接相连的节点,问最少需要多少个士兵才能将整棵树都监视到 题目分析:求最少的节点,以保证每条边都有一个端 ...

  6. HDU - 2389 Rain on your Parade(Hopcroft-Krap算法求二分图最大匹配)

    题目链接:点击查看 题目大意:给出n个人和m个雨伞,t分钟后就要下雨了,现在给出每个人的坐标和速度,以及雨伞所在的坐标,每个雨伞只能容纳一个人,题目问最多有多少个人能不被淋到 题目分析:二分图最大匹配 ...

  7. POJ - 2226 Muddy Fields(最小点覆盖-二分图最大匹配)

    题目链接:点击查看 题目大意:给出一个n*m的地图,地图中'*'代表泥地,'.'代表空地,现在我们有两种木板,一种可以覆盖一行中的任意长度,我们成为行木板,另一种可以覆盖一列中的任意长度,我们成为列木 ...

  8. HDU - 1528 Card Game Cheater(二分图最大匹配)

    题目链接:点击查看 题目大意:题意有点像求田忌赛马的最优解,大概意思就是现在有两个人,每个人都有n张不同的扑克牌,扑克牌的大小首先以点数来确定,点数相同的情况下以花色来决定,红桃(Heart)> ...

  9. HDU - 1150 Machine Schedule(最小点覆盖-二分图最大匹配)

    题目链接:点击查看 题目大意:现在有一个机器A和一个机器B,A机器有n种模式,B机器有m种模式,现在有k次工作需要完成,每次工作的信息为: id x y:编号为id,在A机器要用x模式完成,在B机器要 ...

  10. CodeForces - 387D George and Interesting Graph(二分图最大匹配+暴力)

    题目链接:点击查看 题目大意:给出n个点和m条边组成的有向图,现在我们需要找出一个点作为中心点,然后增加或减少边的条数以达到下面的目标: 除了中心点外,其他的每个点的入度为2且出度为2 中心点和每个点 ...

最新文章

  1. Django学习之路(一)--初识django
  2. windows form窗体应用程序,建一个记事本参考代码,重点是打开,保存,另存为...
  3. rockemq 发送延迟消息_RockeMQ通过代码监控消费者状态
  4. Bug调用其他函数失败
  5. Linux的进程/线程间通信方式总结
  6. 知己知彼 防范攻击:网络攻击步骤与黑客攻击原理
  7. axios在IE下的兼容性处理
  8. 一个字形容大数据_嘉禾数据科学分享(八):一个大数据专业教师眼里的大数据
  9. javascript+div实现鼠标划过,切换层效果
  10. 华三 h3c STP生成树保护配置
  11. linux下获取程序所在目录绝对路径
  12. element table多选和单选
  13. 你的服务器安全么?--服务器防渗透(1)
  14. linux用户打开进程数,Linux 用户打开进程数的调整
  15. android studio模拟器闪一下,android studio连接雷电模拟器 【AS 模拟器】
  16. Linux的一些常用操作命令
  17. php写aaa-zzz,php算法打印aa aaa ab aab直到zzz
  18. 想用FPGA加速神经网络,这两个开源项目你必须要了解
  19. java泡泡龙开源_2019级C语言大作业 - 泡泡龙
  20. 字体引入,不生效问题解决

热门文章

  1. 随机森林(Random Forest)算法原理
  2. -eq、-ne、-gt、-ge、-lt、-le英文意思
  3. 有m个人围成一圈,顺序编号,编号固定,从1道n循环报数,遇到n出圈,依次类推。。。。。
  4. 放弃蚂蚁offer,选择农行软开!
  5. TM1650芯片驱动四位数码管
  6. fir300c固件_斐讯路由器漏洞集合(内置账号及隐藏接口)
  7. ansible register 之用法
  8. C++snprintf的使用
  9. iOS开发之常用第三方框架
  10. 电脑托文件到服务器,本地电脑文件拖入云服务器