前置知识:二分图、图匹配

引入

本文讨论二分图 的最大匹配问题。

生活中一个典型的二分图匹配的例子是男女配对。设有若干男生()和女生(),每个人只能配对一次,且允许配对的组合已由某个列表()限定。此时,二分图最大匹配算法的任务就是在这些限制下,找到最多的配对对数,使尽可能多的人成功配对。

提示

本文假设已知二分图顶点集 的一种划分(染色)方式:。如果事先不清楚二分图的顶点集 的划分方法,可以通过 二分图的染色算法 在 时间内求出这样一个划分。

Kuhn 算法

Kuhn 算法是 Berge 引理 的直接应用。它也是 匈牙利算法 的一部分。

过程

为了求出最大匹配,算法依次枚举所有顶点,求出从它出发的一条增广路,并进行增广。因为增广路的长度总是奇数,所以在二分图中,它的端点必然分别位于左右两个部分。这说明,只需要考虑从左部出发的增广路即可。

为了寻找增广路,可以依据当前的匹配 给二分图定向。从左部的未匹配点出发的增广路(或者任何一条交错路)中,只能沿着非匹配边从左部点到达右部点,再沿着匹配边从右部点到达左部点。因此,可以规定所有非匹配边都指向右部点,而所有匹配边都指向左部点。寻找增广路的问题就转换为从某个未匹配的左部点出发,在有向图中寻找一条简单路径通向某个未匹配点。这一问题很容易通过 DFS 或 BFS 在 时间内解决。

(图中,深色点为匹配点,浅色点为未匹配点,红边为匹配边,黑边为非匹配边,箭头表示当前匹配对应的定向。由图可知,路径 是相对于当前匹配的一条增广路。)

算法开始时,所有边都指向右部点。每次寻找到增广路后,都需要沿着增广路将经过的所有边都反向,以表示它们的匹配状态已经反转。算法结束时,所有指向左部点的边就是匹配边。

因为至多只需要枚举 个左部点 各一次,所以,算法总的时间复杂度为 。

优化

有一些简单的技巧,可以优化 Kuhn 算法的常数:

  1. Kuhn 算法基于 Berge 引理,而后者并不要求事先给出二分图的左右部分。因此,即使在左右两部分未明确划分的情况下,Kuhn 算法也能正确运行,只要图本身是二分图。但是,先将二分图染色,确定好它的左部和右部,往往效率更高。
  2. 因为上文描述的 Kuhn 算法的时间复杂度实际上是 的,所以,可以选取二分图的两个部分中较小的那个作为左部 。
  3. 在寻找增广路时,用于避免重复查找的标记无需每次 DFS 都清空。可以在清空标记前,尝试为所有未匹配的左部点都寻找增广路。在一轮这样的查找中,所有边至多访问一次,复杂度仍然是 的;但是,在一轮查找中,可能找到多条增广路,因此总的轮数 不会超过 ,其中, 为最大匹配。相应地,算法整体复杂度降低到了 。
  4. 寻找增广路时,优先考虑未匹配的右部点,因为这意味着更短的增广路。
  5. 因为 Berge 引理并不要求初始匹配为空,所以,Kuhn 算法开始时,可以随机地选取一些互不相交的边作为初始匹配,以减少后续搜索的次数。如果已经应用优化 3,本优化可以忽略。

虽然最差复杂度仍然是 ,但是,充分优化的 Kuhn 算法效率并不差。但是为了避免个别数据将它卡到最差复杂度,在匹配前需要首先随机打乱边或顶点的顺序。

参考实现

实现时,不需要真正维护定向,只需要为每个顶点都维护与它相匹配的顶点即可。

Hopcroft–Karp 算法

Hopcroft–Karp 算法进一步优化了 Kuhn 算法查找增广路的过程,将总的轮数降低到了 ,从而获得了 的时间复杂度。这一算法实际上是 Dinic 算法 的一种特殊情形。

过程

算法依然是在寻找增广路,但是为了在更少的轮次内完成匹配,算法在每一轮中都采取了如下策略:

  1. 将匹配边定向为指向左部点,非匹配边定向为指向右部点。
  2. 从所有未匹配的左部点出发,在有向图上进行 BFS,记录每个访问到的顶点所在的层数 ,直到某一层出现未匹配的右部点为止。若 BFS 结束仍未找到未匹配的右部点,说明当前匹配已是最大匹配。
  3. 依次从每个未匹配的左部点出发进行 DFS,寻找增广路并进行增广。DFS 时沿着满足层数连续且严格递增(即 )的边向前扩展,且只访问尚未在本轮 DFS 中访问过的顶点。特别地,DFS 中不会访问到前一步 BFS 中尚未访问到的顶点。

用网络流的术语说,步骤 2 是构造了一个层次图,而步骤 3 则是找到了层次图上的阻塞流。所谓层次图,是指它的每条边都必然从这一层指向下一层;而所谓阻塞流,在当前语境下,就是指一组极大的、两两之间没有公共顶点的增广路。步骤 3 得到的这一组增广路必然是极大的:假设不然,存在一条新的增广路,那么在当初枚举到它的起点时,就应当已经找到这样一条路。

比起前文的 Kuhn 算法,Hopcroft–Karp 算法最关键的改变就是在求阻塞流之前,添加了求层次图这一步骤。基于层次图进行 DFS,相当于限制了算法总是沿着最短路径到达各个顶点。这样做的好处是,在算法的不同轮次间,算法找到的增广路的长度是严格递增的。而且,可以证明的是,直到求出最大匹配为止,增广路的长度至多增加 次,其中, 为最大匹配的大小。所以,这就将总的增广的轮次控制在 ,进而得到 的时间复杂度。由于 ,所以,时间复杂度也可以写成更宽松的上界 。

这仅仅是对 Hopcroft–Karp 算法的最差复杂度的估计。实际上,在随机图中,Hopcroft–Karp 算法的时间复杂度有很大概率是 的 1。

优化

在建立层次图时,和一般的 Dinic 算法一样,Hopcroft–Karp 算法在到达未匹配的右部点时就终止。但是,仅仅就二分图匹配问题来说,这样做是没有必要的。而且,因为 BFS 过早终止,限制了后续 DFS 的范围,会导致每轮找到的增广路数目有限,从而拖慢整体匹配效率。在有些图上,它的效率甚至不如经过优化的 Kuhn 算法。所以,一个简单的改进是,不提前终止 BFS,而是为所有可以到达的顶点建立层次图。

参考实现

归约为最大流问题

二分图最大匹配问题可以归约为最大流问题。

如图所示,添加两个顶点分别作为源点和汇点。从源点出发,向每个左部点连接一条边;从每个右部点出发,向汇点连接一条边;并为二分图中的每条无向边,都连接一条从左部点指向右部点的边。所有边的容量都是 。这样得到的有向图中的每个网络流,都和二分图中的一组匹配一一对应,且网络流的容量就是相应的匹配的大小。因此,求解二分图最大匹配,就相当于求解相应的有向图中的最大流。

任何可以解决最大流问题的算法都可以用于解决二分图最大匹配问题。容易发现,Kuhn 算法和 Hopcroft–Karp 算法都是最大流问题中相应算法的特例。同样地,预流推进算法 等同样可以用于解决二分图最大匹配问题。但是,应当注意的是,任何最大流算法,在应用于二分图最大匹配问题时,都需要有针对性地进行相应的优化,以避免过大的常数。

线性规划形式

和其他最大流问题一样,二分图 的最大匹配问题可以写作线性规划问题。如果用 表示边 是否属于匹配,那么,可以得到如下的线性规划问题:

其中, 表示关联关系,即顶点 是边 的端点之一。除了非负限制之外,问题的约束还要求每个顶点 处至多与一条边关联,这正是匹配的定义。因此,所有的匹配都对应于该线性规划可行域中的某些整点。

反过来却不然。在可行解中, 可能是小数,这并不代表任何实际的匹配。尽管如此,对于二分图 ,上述线性规划的所有极点解都是整点。这意味着,目标函数的最优值总能在整点处取得,而无需考虑非整数的情形。这一性质对一般图并不成立,因此,上述线性规划在一般图中并不等价于最大匹配问题。

这一线性规划问题的对偶问题可以写作如下形式:

随后就会看到,这正是二分图的最小点覆盖问题。

Dulmage–Mendelsohn 分解

利用二分图的最大匹配,可以将顶点划分为若干互不相交的子集,从而完整刻画该二分图所有最大匹配的分布及结构特征。这就是 Dulmage–Mendelsohn 分解。算法竞赛中,利用这一分解,可以识别最大匹配中的关键点和关键边,进而判断最大匹配的唯一性或求解二分图博弈等问题。

构造方法

设二分图 的一个最大匹配为 。

如图所示,可以为所有顶点 定义如下三个子集:

  • 偶可达点 ,即所有可以从一个未匹配点出发,沿着偶数长度的交错路可以到达的顶点集合;
  • 奇可达点 ,即所有可以从一个未匹配点出发,沿着奇数长度的交错路可以到达的顶点集合;
  • 不可达点 ,即所有无法从一个未匹配点出发,沿着交错路到达的顶点集合。

可以证明,这样得到的三个顶点集合 有如下性质:

性质

  1. 集合 构成顶点集合的一个划分,且这一划分和最大匹配 的选取无关。
  2. 图 的任一最大匹配都包含 的顶点之间的一个完美匹配,且将 中的每一个顶点都匹配到 中的一个顶点。也就是说,图 的最大匹配的大小等于 。
  3. 图 中不包含连接 中顶点和 中顶点的边。

由此得到的顶点集合的分解 就称为 Dulmage–Mendelsohn 分解。在利用前文所述算法求得最大匹配之后,可以通过 BFS 在 的时间内求出 Dulmage–Mendelsohn 分解。

最大匹配关键点

如果一个顶点 在二分图 的每一个最大匹配中都是匹配点,那么它就称为最大匹配的关键点。下面的结论说明:一个顶点是关键点,当且仅当在一个最大匹配中,不存在从未匹配点出发到达该顶点的偶数长度的交错路。

定理

设二分图 的 Dulmage–Mendelsohn 分解为 。那么,顶点 是关键点,当且仅当 。

因此,要求出最大匹配的关键点,只需要求出 Dulmage–Mendelsohn 分解即可。

最大匹配关键边

类似地,如果一条边 在二分图 的每一个最大匹配中都是匹配边,那么它就称为最大匹配的关键边。二分图的最大匹配是唯一的,当且仅当它的一个最大匹配中,所有匹配边都是关键边。

定理

设二分图 的 Dulmage–Mendelsohn 分解为 ,且 是它的一个最大匹配。那么,边 是关键边,当且仅当 的端点都在 中,边 是 中匹配边,且相对于 不存在一个包含边 的交错环。

因此,要求出最大匹配的关键边,需要按照如下步骤进行:

  1. 求出图 的最大匹配 ;
  2. 按照 将图 的边定向,得到有向图 ;
  3. 进行 BFS 求出 Dulmage–Mendelsohn 分解中的集合 ,即无法通过未匹配点沿着交错路到达的顶点集合;
  4. 利用 Tarjan 算法 求出有向图 的全部强连通分量;
  5. 遍历匹配 中的边,如果它的端点都在 中,但是不在同一个强连通分量中,它就是一条关键边。

得到最大匹配后,后续步骤的时间复杂度为 。

相关问题

利用二分图最大匹配的算法,可以解决其它组合优化问题。

二分图最小点覆盖

最小点覆盖问题是指,在一张无向图中选择最少的顶点,满足每条边至少有一个端点被选。

一般图的最小点覆盖问题是 NP 困难的,但是对于二分图,Kőnig 定理说明它可以归约为最大匹配问题,从而高效求解。定理的证明同时也给出了最小点覆盖的构造。

Kőnig 定理

二分图中,最小点覆盖中的顶点数量等于最大匹配中的边数量。

从网络流的角度看,最小点覆盖问题就是最小割问题:选择左部点,相当于切割它与源点的连边;选择右部点,相当于切割它与汇点的连边。从线性规划的角度看,最小点覆盖问题就是最大匹配问题的对偶问题。因此,König 定理可以看作是 最大流最小割定理 的特殊情形,或者更一般地,线性规划的强对偶定理的特殊情形。

二分图最大独立集

最大独立集问题是指,在一张无向图中选择最多的顶点,满足两两之间互不相邻。

对于一般图,成立如下定理:

定理

图 中,点集 是点覆盖,当且仅当它的补集 是独立集。

推论

图 中,最小点覆盖与最大独立集的大小之和等于顶点数目。

因此,与最小点覆盖问题一样,最大独立集问题对于一般图是 NP 困难的,但是对于二分图它可以归约为最大匹配问题,从而高效求解。

有向无环图最小路径覆盖

最小路径覆盖问题是指,在一张有向图中,选择最少数量的简单路径,使得所有顶点都恰好出现在一条路径中。

一般的有向图上的最小路径覆盖问题是 NP 困难的,但是对于有向无环图,该问题可以归约为二分图最大匹配问题。对于有向无环图 ,可以二分图 如下:

  • 为每个顶点 ,分别建立一个入点 和一个出点 。设全体入点和出点的集合分别为 和 。它们分别成为新图的左部和右部。
  • 为每条有向边 ,建立无向边 。全体无向边的集合就是 。

为此,有如下结论:

定理

有向无环图 的最小路径覆盖与相应的二分图 的最大匹配的大小之和等于顶点数量。

证明是构造性的,因此,很容易根据得到的最大匹配构造出相应的最小路径覆盖。而且,这个构造说明,对于一般的有向图,这个归约不再成立,正是因为二分图中的匹配可能对应着有向图中的环。

特别地,对于集合 和它上面的偏序关系 ,可以建立有向无环图 。此时,根据 Dilworth 定理,图 的最小路径覆盖的大小,就等于它的最长反链的长度,也就是偏序集 的宽度。因此,本节实际上给出了任意偏序集的宽度的高效计算方法。

例题

应用二分图匹配的难点在于建图,本节通过一些例题展示建图的技巧。

有一个 01 方阵,每一次可以交换两行或两列,问是否可以交换使得主对角线(左上到右下)全都是 1。

有 个律师,都被指控有欺诈罪。于是,他们需要互相辩护,确保每一名律师都被释放。这 个律师有 对信任关系,一个信任关系 表示 可以为 辩护。任何一个受到辩护的律师都会被无罪释放,除了一个例外:如果 和 互相辩护,他们都会被判有罪。

求是否可以使得每一名律师都被释放。

用一些 的砖精确覆盖一个 的网格,砖可以旋转,其中有一些格子不能覆盖。

有 个共有 个元素的可重集,每一次从某一个可重集里面删除一个元素,然后查询「在每一个可重集里面选至多一个元素,可以达到的最大 」。

有一个 的国际象棋棋盘,其中一些位置不能放棋子,问最多可以放多少个马使得这些马不会互相攻击。

习题

参考资料

Footnotes

  1. Bast, Holger; Mehlhorn, Kurt; Schäfer, Guido; Tamaki, Hisao (2006), “Matching algorithms are fast in sparse random graphs”, Theory of Computing Systems, 39 (1): 3–14. ↩