图论匹配 学习笔记

图论匹配 学习笔记

二分图最大匹配算法

算法核心在于找增广路。

交错路是一条路径,路径上相邻的两个点所在的部不同,且路径上相邻的两条边一条匹配一条不匹配。

增广路是一条从左部出发长度为奇数的交错路。

所以对于一个匹配 \(M\),它是最大匹配 \(M^*\) 当且仅当没有增广路了。

证明:

如果有增广路,那么它一定不是最大匹配,因为可以通过交替增广路上的边匹配情况使匹配至少增加 1。

证明另一方面,欲证:如果一个匹配不是最大匹配,它一定可以找到一个增广路。

考虑 \(M\oplus M^*\), 因为 \(M, M^*\) 度数都不超过 1,所以它们的异或(对称差)的每个点度数不超过 2,所以最后一定得到的是若干个环和若干个路径,则至少存在一个连通块里 \(M\) 的边比 \(M*\) 的边少,否则 \(|M| \ge |M^*|\),则它是最大匹配与假设矛盾,而这个连通块一定是一条路径,而这条路径就是一个 \(M\) 的增广路,证毕。

所以我们只需要设计一个算法,不断找出增广路直到找不到,就找到了一个最大匹配。

偏序关系

我们定义 \((S, *)\) 表示一个集合 \(S\),内部元素满足偏序关系 \(*\)

一个偏序关系 \(*\) 需要满足三个性质(\(a, b, c\in S\)):

  1. 传递性

\(a * b\wedge b*c \Longrightarrow a*c\)

  1. 自反性

\(a*a\) 成立。

  1. 反对称性

\(a*b\wedge b*a\Longrightarrow a=b\)

我们熟知的 \(\le\) 就是一个非严格偏序关系。

Dilworth 定理

偏序集中,最长反链长等于最小链覆盖。

反链是一个偏序集的子集,其两两元素没有偏序关系。

链覆盖是一系列偏序集的子集,它们的并等于偏序集,每个子集内部都有偏序关系。

证明:

对于一个链覆盖 \(CC\) 和最长反链 \(A\)\(|CC|\ge |A|\),因为无论如何,一条链都不能同时覆盖两个 \(A\) 的元素。

发现偏序关系构成了一张 DAG,采用最小路径覆盖问题的拆点方式,一个点拆成入点和出点,这样我们求出此二分图的最大匹配 \(M\),根据 Konig 定理,\(|M| = |C| = n - |CC|\)\(C\) 是最小点覆盖。

断言:最大反链集合是 \(\{A, i|u_i\notin C, v_i\notin C\}\)

首先对于 \(i, j\in A, i\ne j\)\(i ,j\) 没有偏序关系,假设有,因为 \(u_i, v_i\notin C\),所以最小点覆盖没有覆盖这条边,与定义矛盾,故 \(A\) 为一个反链。

观察到 \(|A|\ge n - |C|\),因为如果所有最小点覆盖选取的点都不同,那么 \(|A| = n - |C|\),实际上如果相同,那么 \(|A|\) 必然更大,故不等式成立。

可得到 \(|CC|\le |A|\),结合一开始的不等式,证明完毕。

这是构造性的证明,可以通过此证明找到最大反链。

Kuhn–Munkres 算法(KM, 匈牙利算法)

定义

解决最佳匹配问题。

如果最佳匹配有负数,把所有的边权都加上一个常数即可,因为最佳匹配一定是最大匹配。

定义顶标 \(l(u)\),如果 \(\forall (x_i, y_j), l(x_i) + l(y_j)\ge w_{i, j}\),则称 \(l\) 是可行顶标,如果 \(G(V, E)\)\(V =\{x_1,x_2,...,x_n, y_1,y_2,...y_n\}, E = \{(x_i, y_j) | l(x_i)+l(y_j)=w_{i,j}\}\)\(G\) 是相等子图。

引理:如果一个可行顶标的相等子图有最大匹配 \(M, |M| = n\)\(M\) 是最佳匹配。

根据可行顶标的定义可以简单证明。

算法流程

  1. 随机一个可行顶标 \(l\)
  2. 在相等子图里找一个最大匹配,如果 \(|M| = n\) 则已找到最佳匹配,否则调整 \(l\)

如何调整呢?

考虑目前已有的最大匹配,从所有未匹配的左部点为根找出一棵交错树,那么我们设左部在树中的点所组成的集合为 \(S\),右部的为 \(T\)

性质:

  1. \(S, \bar T\) 间无边
  2. \(\bar S, T\) 间只有非匹配边

此时我们为 \(S\) 中顶标减去 \(a(a > 0)\),为 \(T\) 中顶标加上 \(a\),这样一来,\(S, T\) 中的所有匹配边不变,然而因为减少了 \(S\) 的顶标,故可能 \(S, \bar T\) 中会产生新的边,因为 \(l(x_i)+l(y_j)\ge w_{i,j}\) 更紧了。

为了至少产生一条这样的边,可以令 \(a\) 为:

\[\min_{x_i\in S, y_i\in \bar T}(l(x_i)+l(y_i)-w_{i ,j}) \]

由此可见,最多 \(n\) 次调整后可以扩展新的最大匹配,因为最大匹配大小是 \(n\) 级别的,所以最多有 \(n^2\) 次调整,为了优化调整复杂度,考虑定义一个数组 \(slack_i = \min_{x\in S}(l(x) + l(i) - w_{x, i})\),每次扩展 \(S\) 和调整顶标的时候都可以 \(O(n)\) 维护,计算 \(a\) 的复杂度就变为了 \(O(n)\)

例题

P4298 [CTSC2008] 祭祀

给定 DAG,求最长反链长度,最长反链方案,有多少个点可以成为反链上的点。

题解:https://www.cnblogs.com/MoyouSayuki/p/18136943

posted @ 2024-04-14 18:56  MoyouSayuki  阅读(10)  评论(0)    收藏  举报
:name :name