初次接触到二分图最大匹配是在http://acm.hdu.edu.cn/showproblem.php?pid=2063
离散数学中有涉及到二分图,完全二分图,匹配,最大匹配及完全匹配的定义,这里就不多做解释。简单介绍一下增广路的概念及其性质。
设M为二分图G的一个匹配。M中的端点称为M-顶点,其它顶点称为非M-端点。则增广路径:除了起点和终点是非M-顶点,其它路径上所有的点都是M-顶点,且它的边为匹配边和非匹配边交替出现。
增广路径的性质:
- 有奇数条边。
- 起点在二分图的左半边,终点在右半边。
- 路径上的点一定是一个在左半边,一个在右半边,交替出现。(其实二分图的性质就决定了这一点,因为二分图同一边的点之间没有边相连,不要忘记哦。)
- 整条路径上没有重复的点。
- 起点和终点都是目前还没有配对的点,而其它所有点都是已经配好对的。
- 路径上的所有第奇数条边都不在原匹配中,所有第偶数条边都出现在原匹配中。
- 最后,也是最重要的一条,把增广路径上的所有第奇数条边加入到原匹配中去,并把增广路径中的所有第偶数条边从原匹配中删除(这个操作称为增广路径的取反),则新的匹配数就比原匹配数增加了1个。
以上7条性质是借鉴某大牛的。
了解了增广路的定义以及性质之后,我们仔细理解第7条性质。因为增广路径的长度为奇数,我们不妨设为2*K+1,又因为第一条是非匹配边,且匹配边与非匹配边交替出现,所以非匹配边有K+1条,匹配边有K条。此时,我们做取反操作,则匹配边的个数会在原来的基础上+1。求最大匹配的“匈牙利算法”即是此思想:无论从哪个匹配开始,每一次操作都让匹配数+1,不断扩充,直到找不到增广路径,此时便得到最大匹配。
匈牙利算法的基本模式:
初始时最大匹配为空
while (找得到增广路径)
do 把增广路径加入到最大匹配中。
如果二分图的左半边一共有n个点,最多找n条增广路径,如果图中有m条边,每一条增广路径把所有边遍历一遍,所以时间复杂度为
O(n*m);
从学二分图匹配中较为重要的三个公式:
二分图最小顶点覆盖 = 二分图最大匹配;
DAG图的最小路径覆盖 = 节点数(n)- 最大匹配数;
二分图最大独立集 = 节点数(n)- 最大匹配数;
二分图匹配关键思想在于构图(个人意见哈),能够把一个实际问题通过构图和二分匹配联系起来是比较重要的。
贴一下2063代码:
相关练习:HDU-1068, HDU-1150 ,HDU-1151 ,HDU-1281 ,HDU-1498, HDU-1528 ,HDOJ-1507