网络流学习笔记(旧)
发现其实整理不完所有内容,干脆把所有不会的记了算了 qwq。
基础定义
网络 \(G = (V, E)\) 是一张有向图,其中的边 \((x, y) \in E\) 都有一个权值 \(c(x, y)\),称为 容量。特别的,对于 \((x, y) \notin E\) 可以认定 \(c(x, y) = 0\)。
与一般有向图的区别在于,\(\exist s, t \in E\) 称为网络的 源/汇点,满足 \(s\) 只有出边、\(t\) 只有入边。可以认为 \(s\) 拥有有 无限的流。当然,一部分特殊的网络可能 有多个甚至没有 源汇点。
对于网络 \(G\),流 (流量)\(f\) 指一个 \(E\) 到整数(实数)集的函数,(人话就是边的 实际流量,)满足:
- 容量限制:对于每条边,实际流量不超过其容量,\(0 \le f(x, y) \le c(x, y)\);
- 流量守恒:除源汇点外,所有节点不额外储存流,流入总量等于流出总量,\(\forall x: \sum_{y \in V} f(y, x) = \sum_{y \in V} f(x, y)\);
- 斜对称性:\(f(x, y) = -f(y, x)\),这个相当于定义了负流。
对于流 \(f\),记其流量为 \(\lvert f \rvert\)。
同时定义 可行流 为一条从源点到汇点的合法路径;残量 为每条边的 \(c(x, y) - f(x, y)\)。上述三种量构成的网络分别定义为 容量网络、流量网络、残量网络。特别的,残量网络上的可行流又叫作 增广路。
以及,对于点集的一个划分 \(\{S, T\}\) 满足 \(s \in S, t \in T\),称之为 割,并定义其容量为 \(\left\| \{S, T\} \right\| = \sum_{x \in S, y \in T} c(x, y)\)。
最大流最小割定理
证明 FF 增广的正确性,等价于证明 最大流最小割定理,即一张网络的 最小割容量 等于其 最大流流量。下面从一个引理出发证明这个定理。
引理:对于网络 \(G\) 与任意流 \(f\)、割 \(\{S, T\}\),有 \(\lvert f \rvert \le \left\| \{S, T\} \right\|\)。其中,取等号当且仅当 \(\forall x \in S, y \in T: f(x, y) = c(x, y), f(y, x) = 0\)。
Proof:
定义点 \(x\) 的 净流量 为 \(f(x) = \sum_{y \in V} f(x, y) - f(y, x)\),容易有 \(x \neq s, t \Rightarrow f(x) = 0\)。则:
取等号的两个条件分别对应倒数第一、第二个小于等于号。(莫名感觉这些加入无用量恒等变形证明好抽象……)
考虑证明两种状态均可取到来证明原定理。考虑一张无法继续增广的剩余网络,记 \(s\) 可到达的集合为 \(S\),以及 \(T = V \setminus S\),显然 \(\{S, T\}\) 是一个 割(因为 \(t \in T\))且 \(\left\| \{S, T\} \right\| = 0\)。于是 \(\forall x \in S, y \in T\):
- 若 \((x, y) \in E\),则 \(c'(x, y) = 0 = c(x, y) - f(x, y)\),有 \(f(x, y) = c(x, y)\);
- 反之若 \((y, x) \in E\),则 \(c'(x, y) = 0 = c(x, y) - f(x, y) = 0 - f(x, y) = f(y, x)\),有 \(f(y, x) = 0\)。
写一遍似乎没难么难理解证明过程了,最小割也就不用讲了。怎么感觉这部分和 OI Wiki 长得一样?
Dinic 的复杂度
当前弧优化 是 Dinic 的复杂度保证,而 多路增广 是 Dinic 的常数优化。
对于 一般网络,复杂度应为 \(\mathcal{O}(n \times n m)\),因为 层数单调 总计增广 \(\mathcal{O}(n)\) 次,然后每次 DFS 复杂度 \(\mathcal{O}(n)\) 并且 至少减掉一条边,有单次增广 \(\mathcal{O}(n m)\)。
同时也有关于 值域 的增广上界。设 \(S = \sum \min(inC_{i}, outC_{i})\),如果在第 \(\sqrt{S}\) 轮增广之前就已经结束的话,不用管;否则此时的 增广路长度 不小于 \(\sqrt{S}\),则会存在 某两层之间形成的割 大小不超过 \(\sqrt{S}\),也就是最大流不超过 \(\sqrt{S}\),最多再流 \(\sqrt{S}\) 次。
对于 单位容量网络,复杂度应为 \(\mathcal{O}(\min(m^{\frac{1}{2}}, n^{\frac{2}{3}}) \times m)\),单轮增广的 \(m\) 是由于每条边只被走一次,增广轮数的 \(n^{\frac{2}{3}}\) 则需要类比上面的值域分析:假设已经进行了 \(2 n^{\frac{2}{3}}\) 轮增广,则最坏情况下每层平均 \(\dfrac{1}{2} n^{\frac{1}{3}}\) 个节点,最多有 \(n^{\frac{2}{3}}\) 曾包含点数不小于 \(\dfrac{1}{2} n^{\frac{1}{3}}\) 个节点。于是至少有相邻的俩层点数都不超过 \(n^{\frac{1}{3}}\),最坏情况下形成一个大小为 \(n^{\frac{2}{3}}\) 的割,也就是最大流不超过 \(n^{\frac{2}{3}}\),总共进行 \(\mathcal{O}(n^{\frac{2}{3}})\) 次增广。
单位容量网络 不等价于 单位网络,单位网络在其基础上要求 \(in_{i} = 1 \lor out_{i} = 1\),二分图 就是一种经典的单位网络。结合第二、三条不难的出其复杂度为 \(\mathcal{O}(m \sqrt{n})\),或者 OI Wiki 上有个不太一样的证法。
最小割建模
一般建模
一个比较常用的验证方式是,假定存在某种不合法情况,分析是否 还存在可行流。或者考虑最小割的意义是 分出了 \({S', T'}\)(这个可以用来 构造 最小割),直接分析某个点分属的集合来判定。以及问题是对于最小化的?
- 把一个物品当成一条 容量等于权值 的边,割这条边 代表选这个物品;
- 多个物品 恰好选一个,则把它们 串在同一条链上;
- 选 \(A\) 不选 \(B\),边 \(A\) 起点(前)往边 \(B\) 终点(后)连 容量为 \(\infty\) 的边,如果割了 \(A\) 则边 \(A\) 之前可以看作 流量无限,那么通过上述加边就能补掉 \(B\) 割掉的流;
- 特殊的,当 3. 中的限制边是 从 \(S\) 方向流向 \(T\) 方向 的时候,会出现同一条链割两条边的情况。两种解决方法:一、链上加入 反向 \(\infty\) 边;二、从前/后依次 补上 没有连边的情况。本质是保证 \(S\) 只流到 一条链的前缀(见 P3227 与 P6054)
最大权闭合子图
若干带有 可负权值 的物品,给定若干条件形如选 \(i\) 必须选 \(j\),要最大化选物权值和。那么 正权物品 连 \((S, i, v_{i}), (i, T, 0)\),否则连 \((S, i, 0), (i, T, -v_{i})\),意义都是割前者不选、割后者选;限制 \(i, j\) 连 \((i, j, \infty)\),如果 \(i\) 割了而 \(j\) 不割就会有 \(S \rightarrow i \rightarrow j \rightarrow T\) 的增广路,不合法。于是答案等于 正权物品权值和减 这张图上的 最小割。
平面图最小割
经典案例是 网格图。对于这类题目,通常是建出网络后发现 点数过多,\(\mathcal{O}(n^{2} m)\) 完全跑不过去。这个时候可以考虑从 \(S, T\) 各引一条射线,将平面分成两部分 \(S', T'\),则这个平面图的最小割 等于对偶图的最短路。由欧拉公式 \(f = m - n + 2\) 可以得到对偶图点数为 \(\mathcal{O}(n)\),上个 dijkstra 就是 \(\mathcal{O}(n \log n)\) 的复杂度。发现 Alex_Wei 的博客写得太详细了,要学习学习 orz。
最小点覆盖与最大独立集
对于 二分图 的。设最小点覆盖是 \(C\),最大独立集是 \(I\),由:
- \(\complement_{V} C \subseteq I \Rightarrow \lvert C \rvert + \lvert I \rvert \ge n\);
- \(\complement_{V} I \supseteq C \Rightarrow \lvert I \rvert + \lvert C \rvert \le n\)。
可以得到 \(\lvert C \rvert + \vert I \rvert = n\)。考虑 最小点覆盖,这等价于一个一般最小割模型问题,即选 \(A\) 不选 \(B\),然后在一般建图的基础上,发现左部点、右部点之间的边从 \(\infty\) 改成 \(1\) 最小割是不会变的,这就等价于最大匹配。
最小链覆盖
有点意思,先考虑基础的求最少可以把一张 DAG 分成多少条 不交 的链。这个问题里的 匹配关系 在于链上的 前驱与后继,对于一个点存在两个匹配;同时自然的想到没有匹配的点会产生 \(1\) 的贡献,因此可以构建出 拆点二分图模型。对一个点拆成 \(x_{1}, x_{2}\),一条边 \(x \rightarrow y\) 连 \(x_{2}, y_{1}\),那么答案是 \(n\) 减去最大匹配,也就是这张二分图的 最大独立集。
对于链 可交 的情况,也就是每个点现在 至少 包含在一条链里。对于这种情况,提前做一个 传递闭包(人话讲就是每个点向其能到达的点连边)后就变成上面不交的情况了,因为这个操作相当于使找前驱后继时 跳过一段已匹配点,仍然满足原图上的 连通性;同时最大流应该可以保证答案最优,所以是有正确性的。
直接把反链给并上来得了,实际上是 序理论 的 Dilworth 定理:最长反链 长度 等于最小 可交 链覆盖。发现网络流问题里的严谨证明都很抽象。
强制二分图匹配
也是个奇妙的问题,强制若干点必须在匹配内,构造一组合法解。考虑把 左/右部强制点 和 所有右/左部点 单独拎出来跑两遍二分图匹配,若有任意一次不是 完备匹配,则无解;否则将所有 匹配边 加入新图,发现一个点 \(d \le 2\),也就是说这张二分图上 只存在链和环。环是好处理的,由于不存在奇环,交错取边就可以解决;对于链,妙的一点在于如果最后一个点独立了,那它 一定不是强制点,否则其一定有 \(2\) 条边连着,因此可以不管。于是 \(\mathcal{O}(m \sqrt{n})\) 做完了。