匈牙利算法与套题

匈牙利算法与套题


匈牙利算法是利用增广路来找二分图里的最大匹配问题。

二分图的概念:

设G=(V, E)是一个无向图。如果顶点集V可分割为两个互不相交的子集U和V,并且图中每条边连接的两个顶点一个在U中,另一个在V中,则称图G为二分图。

匈牙利算法与套题_第1张图片

如何判断给你的图为一个二分图:染色法(BFS判断)

  • 染色法就是将二分图中的两个不相关的子区间染成不同颜色(如上图中U被染成蓝色,V被染成绿色),这样在这个图里面的每条边的端点都是不同的颜色。 — wiki
  • 所以在一个图中,我们随便从一个点从0开始进行BFS(广度优先搜索),每次搜索到的点先进行判断是否被搜过,如果没有被搜过,那么这个搜到的点 = 目前的点+1.如果被搜过,就要判断两个值是否同奇或者同偶,如果不满足同奇或者同偶,就说明不满足染色法,就不是一个二分图。

下面是一个图,用染色法标记发现它是一个二分图

匈牙利算法与套题_第2张图片
上面的图转换成二分图为:
匈牙利算法与套题_第3张图片

二分图中几个小知识:

  1. 匹配:根据染色法边集E的任意两条边不依附同一个顶点
  2. 最大匹配:最大匹配数也是最小覆盖数,要到把当前二分图中的匹配数找到不能找为止
  3. 完全匹配:匹配完图G中所有点。
  4. 取反:在一条增广路中,把未匹配的变成匹配并把匹配的变成未匹配
    • 注:完全匹配一定是最大匹配,最大匹配不一定是完全匹配。

增广路的概念:

在网上搜了一下增广路发现有点看不懂:

  • 若P是图G中一条连通两个未匹配顶点的路径,并且属于M的边和不属于M的边(即已匹配和待匹配的边)在P上交替出现,则称P为相对于M的一条增广路径(举例来说,有A、B集合,增广路由A中一个点通向B中一个点,再由B中这个点通向A中一个点……交替进行)。 —百度百科

然后在网上疯狂找资料找到了一个易懂的:通过交替路找增广路

  • 交替路:再G中的边,匹配的边和未被匹配的边交替出现
  • 增广路:从未匹配的边开始,走交替路,并以未匹配的边结束。

匈牙利算法:

  1. 置M为空。
  2. 用DFS(深度优先搜索)寻找增广路,取反获得最大匹配M’代替M。
  3. 重复2,直到找不到增广路为止。
    注: M为二分图以匹配边的集合。

当时我在这里不理解,为什么找到了增广路取反得到的新M集合(M’)就要比旧M集合更优?

其实这里你画一下图就很好理解了,这里我先用文字描述一下:因为增广路是从未匹配开始到未匹配结束,所以你对增广路取反必定会在原来匹配边的基础上增加一条匹配边。

如下图:上图为旧M集合,下图为取反后的新M集合。可看出取反后的M集合里的匹配条数多了一条。

匈牙利算法与套题_第4张图片

匈牙利算法题集:

匈牙利板子题:POJ3041

题意:输入两个数n,m。n为点集,m为边集。然后m组数据是从X点集到Y点集的边。要你求最小覆盖数,也就是最大匹配数。
点击查看代码(DFS+邻接矩阵)
点击查看代码(BFS+邻接矩阵)

hdu2063

点击查看代码(BFS+邻接矩阵)

二分图判定:hihocoder1121

BFS+邻接表


参考资料:

趣写算法系列之–匈牙利算法
匈牙利算法
二分图匹配——匈牙利算法和KM算法
二分图的最大匹配、完美匹配和匈牙利算法

你可能感兴趣的:(ACM)