二分图最大匹配与其应用

二分图最大匹配与其应用_第1张图片

部分定义

  • 传递闭包

    一个图。如果图 G 中点 i 到点 j 存在通路,那么在传递闭包中有边 i>j

  • 二分图

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

  • 匹配

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

  • 增广路

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

增广路的性质:

1 有奇数条边。

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

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

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

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

同上

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

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

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

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

既然我们知道增广路的取反可以增加匹配边数,那我们就不断的去找增广路去取反他,直到没有为止。当找不到增广路时,那么当前匹配就是最大匹配(增广路定理),匈牙利算法正是这么做的。

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

伪代码

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定理:二分图的最小顶点覆盖数等于二分图的最大匹配数。

(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 ↩

你可能感兴趣的:(easy)