二分图和网络流基础知识记录
-
网络最大流等于最小割。构造该割的一种方案的方法是从原点(或汇点)出发只通过残余边到达所有点,将其作为S(或T),然后S->T的所有边是一种最小割。最小割的可行边是跑完最大流以后残余网络上进行强连通缩点,两端不在同一个SCC内的满流正向边;必须边是一个端点和s在同一SCC,另一端点和t在统一SCC的满流正向边。注意不是满流正向边的不会去割。
-
最小割模型可以用来模拟“具有某种关系的两个对象必须放弃一个”的模型,其典型应用是求解二分图最大独立集。
-
设一个二分图左右点集大小为 \(n\),最大匹配为 \(m\),则最大独立集大小为 \(n-m\),最小点覆盖为 \(m\),且一组最大独立集的补集即为一组最小点覆盖。最大独立集的一种求法是跑出匹配以后从左部所有非匹配点出发,走非匹配边到右边,再从右边走匹配边回左边,再走非匹配边到右边……标记所有该过程中路过的点,然后选右边的标记点和左边非标记点。更简单的方法是直接用最小割构造。
-
DAG的最小不重路径覆盖可以转化为合并路径,并最终转化为二分图匹配来解决。DAG的最小重复路径覆盖可以将DAG传递闭包以后(转化为偏序集)进行不重复路径覆盖。
-
Dilworth定理:偏序集最小链覆盖的大小等于最长反链长度,也就是 \(n-m\)。构造这一最长反链的方法是构造出二分图以后求最大独立集,如果一个点对应的左右部点都在最大独立集内那么将其加入反链。其正确性显然,而最优性证明如下:
考虑最大独立集中的点数为 \(2n-m\),那么如何计算左右部点都在该独立集内的原图点个数呢?计数这些原图点时,考虑最大独立集点数的贡献:至少有一部点在最大独立集内的原图点贡献 \(1\) 的大小,而上述点额外贡献 \(1\) 的大小,那么前者的贡献至多为 \(n\),所以后者至少有 \(2n-m-n = n-m\),而最长反链的长度至多是 \(n-m\),所以这些原图点就是一种最长反链。
-
Dinic网络流的时间复杂度极限是 \(O(V^2E)\),但是能处理点数 \(10^4-10^5\) 的流网络。对于二分图,时间复杂度是 \(O(E\sqrt{V})\),实际应用中非常快。
-
费用流的SPFA麻烦加上
inque
,对偶图最短路Dijkstra麻烦加上vis
,Dinic的增广必须有当前弧,否则会TLE。贪心转化的费用流一般没有负环。 -
一些贪心型的网络流和费用流模型如果你可以预测到一些点总是优于另一些点可以写个动态加点,前者不跑完就不要去考虑后面的点。一些看起来比较特殊(尤其是在平面上或者序列上根据规则选择连边)的图很可能是二分图,考虑一下怎么染色可以降低复杂度。
-
最小化最小割的边数:一种方法是给所有边加上一个很大的容量然后照常跑最大流。另一种方法是将原先最大流跑出来以后,将所有满流边设为 \(1\),其他边设为 \(\infty\),然后再求一遍最小割。
-
丐版 Capacity Scaling:从大到小枚举一个阈值 \(2^t\),每次只考虑容量大于等于阈值的边,跑最大流,然后加入新边接着跑。
复杂度似乎不能保证是 Capacity Scaling 的复杂度,但是一般不会比常规的最大流写法更劣。根据题解区说法似乎可以保证是 \(\Theta(nm\log C)\),能在大多数场景下很大程度提升速度,可以用来直接替代普通最大流。在普通费用流中使用这个东西,似乎有可能劣化(多 \(\log\)),不建议无脑上。费用流的正版 CS 更是慢的不行,总是会跑满,完全不建议在比赛中使用。
常见网络流问题的线性规划形式
\(c_e, c_{u, v}\) 表示 capacity,\(w_e, w_{u, v}\) 表示 cost。\(f_e, f_{u, v}\) 表示当前流量,\(d_u\) 表示初始流量,即要求 \(\sum\limits_{p}f_{u, p} - \sum\limits_{q}f_{q, u} = d_u\)。
最小割
考虑对于每个点设置 \(X_i \in \{0, 1\}\) 表示是否在 \(S\) 块内。则形式为:
(带有初始流量的)最小费用(循环)流
其它费用流问题可以化为这个形式。
是一个最小化形式的线性规划问题。
费用流对偶
下面考虑它的对偶形式,\(X_{u, v}\) 是边流量限制的对偶,\(Y_u\) 是点流量平衡的对偶。
显然 \(X_{u, v} = \max\{0, Y_u - Y_v - w_{u, v}\}\),于是:
它的一个常见用法是设 \(c_{u, v} = \infty\),则变成了有若干个限制 \(Y_u - Y_v - w_{u, v} \le 0\),\(\max \sum\limits_u d_uY_u\)。