匈牙利算法与套题
匈牙利算法是利用增广路来找二分图里的最大匹配问题。
二分图的概念:
设G=(V, E)是一个无向图。如果顶点集V可分割为两个互不相交的子集U和V,并且图中每条边连接的两个顶点一个在U中,另一个在V中,则称图G为二分图。
如何判断给你的图为一个二分图:染色法(BFS判断)
- 染色法就是将二分图中的两个不相关的子区间染成不同颜色(如上图中U被染成蓝色,V被染成绿色),这样在这个图里面的每条边的端点都是不同的颜色。 — wiki。
- 所以在一个图中,我们随便从一个点从0开始进行BFS(广度优先搜索),每次搜索到的点先进行判断是否被搜过,如果没有被搜过,那么这个搜到的点 = 目前的点+1.如果被搜过,就要判断两个值是否同奇或者同偶,如果不满足同奇或者同偶,就说明不满足染色法,就不是一个二分图。
下面是一个图,用染色法标记发现它是一个二分图
二分图中几个小知识:
- 匹配:根据染色法边集E的任意两条边不依附同一个顶点
- 最大匹配:最大匹配数也是最小覆盖数,要到把当前二分图中的匹配数找到不能找为止
- 完全匹配:匹配完图G中所有点。
- 取反:在一条增广路中,把未匹配的变成匹配并把匹配的变成未匹配。
- 注:完全匹配一定是最大匹配,最大匹配不一定是完全匹配。
增广路的概念:
在网上搜了一下增广路发现有点看不懂:
- 若P是图G中一条连通两个未匹配顶点的路径,并且属于M的边和不属于M的边(即已匹配和待匹配的边)在P上交替出现,则称P为相对于M的一条增广路径(举例来说,有A、B集合,增广路由A中一个点通向B中一个点,再由B中这个点通向A中一个点……交替进行)。 —百度百科
然后在网上疯狂找资料找到了一个易懂的:通过交替路找增广路
- 交替路:再G中的边,匹配的边和未被匹配的边交替出现
- 增广路:从未匹配的边开始,走交替路,并以未匹配的边结束。
匈牙利算法:
- 置M为空。
- 用DFS(深度优先搜索)寻找增广路,取反获得最大匹配M’代替M。
- 重复2,直到找不到增广路为止。
注: M为二分图以匹配边的集合。
当时我在这里不理解,为什么找到了增广路取反得到的新M集合(M’)就要比旧M集合更优?
其实这里你画一下图就很好理解了,这里我先用文字描述一下:因为增广路是从未匹配开始到未匹配结束,所以你对增广路取反必定会在原来匹配边的基础上增加一条匹配边。
如下图:上图为旧M集合,下图为取反后的新M集合。可看出取反后的M集合里的匹配条数多了一条。
匈牙利算法题集:
匈牙利板子题:POJ3041
题意:输入两个数n,m。n为点集,m为边集。然后m组数据是从X点集到Y点集的边。要你求最小覆盖数,也就是最大匹配数。
点击查看代码(DFS+邻接矩阵)
点击查看代码(BFS+邻接矩阵)