Loading

[专题总结]二分图和网络流(理论篇)

二分图

二分图最大匹配

二分图的一组匹配就是一个边集,其中任意两条边没有公共顶点。

求最大匹配的过程:建一个图, \(S\) 向左部连 \(1\),右部向 \(T\)\(1\) ,跑最大流,中间的边被流了就是匹配边。

点覆盖

是一个点的集合,使得所有的边至少有一个顶点在该集合内

  • 最小点覆盖=最大匹配

证明: 首先最小点覆盖的下界是最大匹配,因为所有匹配边两边至少有一个点需要选择。

构造一种选择恰好最大匹配个点的方案,给出构造方法。

先跑出最大流,然后从右侧所有非匹配点开始 dfs, 从右侧向左侧走,只能走非匹配边,从左侧到右侧走,只能走匹配边,最后,取出所有左边的被 dfs 到的点和右边的未被 dfs 到的点,就是最小点覆盖。

证明:一条边不被覆盖当且仅当左边未被 dfs 到,右边被 dfs 到。

右边被 dfs 到了,他如果是非匹配点,他必将便利左侧所有相连点。

如果他是匹配点,那么他肯定是由左侧的匹配点过来的,过来的左侧点肯定被访问了,其他的左侧点会被他访问。

所以,一个与右侧被 dfs 到的点相连的所有左侧点都会被 dfs 到,不存在上述情况。

似乎还叫什么定理,例题:https://www.luogu.com.cn/problem/P6220

Tip: 最小割中的割边:并不是剩余容量为 \(0\) 就是割边,找割边需要先跑最大流,再从 \(S\) 开始 \(dfs\) 找到属于 \(S\) 集合的点,剩下的点属于 \(T\) 集合,两个集合之间的连边容量必定为 \(0\) ,是割边。

独立集

是一个点的集合,使得这个集合内任意两个点没有边相连

  • 最大独立集=\(|V|-\)最小点覆盖

证明:首先独立集上界是 \(|V|-\) 最大匹配,因为如果选择更多,根据鸽巢原理,至少会有两个点同时在最大匹配中,必定不独立。

构造一种 \(|V|-\)最小点覆盖的方案,就是选择最小点覆盖的补集。

因为最小点覆盖把每条边的至少一个顶点覆盖了,所以剩下的点连的边已经没有完整的边了,所以肯定是独立集。

边覆盖

是一个边的集合,是的所有的点都是这个集合中的某条边的顶点

  • 最小边覆盖=最大独立集

证明:首先最小边覆盖的下界是最大独立集,因为最大独立集内每个点都需要单独的一条边去覆盖。

构造一种最大独立集条边的方案,先选择所有匹配边,假设有 \(m\) 条。

这时候,还剩下 \(n-2m\) 个点没有覆盖,因为最小点覆盖的集合肯定是匹配点的集合,所以所有未匹配点都属于最大独立集,给这 \(n-2m\) 个每个点点任意选一条边即可。

最后选了 \(m+n-2m=n-m\) 条边,等于最大独立集。

路径覆盖

对于一个 DAG,是一个路径的集合,使得每个点都被至少一条路径覆盖

先把每个点 \(x\) 拆成入点 \(x_1\) 和出点 \(x_2\) ,若 \((u,v)\),则在 \(u_1,v_2\) 之间连一条边,不难发现新图是一个二分图。

最小不相交路径覆盖= \(|V|-\) 最大匹配。

证明:考虑一开始,匹配 \(0\) 条边,需要 \(|V|\) 个路径才能覆盖,每次匹配相当于把每个两个点放到一个集合,也就相当于少一条路径就能覆盖,最大匹配就是最小的路径覆盖。

最小可相交路径覆盖:先传递闭包,再最小不相交即可。

证明:原图传递闭包后,一条新图中的路径可以表示原图中一条断断续续的路径,把原图中相交的部分在新图中改成断断续续,就不相交了。

Dilworth 定理 与 集合论相关

传递闭包

跟2017年的论文里面学习,只学习了一部分。

\((i,j)\) 有边, \((j,k)\) 有边,则让 \((i,k)\) 有边。

实现采用和 Floyd 算法类似的方式,枚举中间点。

\(f_{i,j,k}\) 为只考虑前 \(i\) 个点, \(j,k\) 是否有关系。

转移考虑是否经过通过第 \(i\) 个点, \(m_{i,j,k}=m_{i-1,j,k}|(lk_{j,i}\&lk_{i,k})\)

可以滚动数组,所以有代码

for(R k = 1; k <= n; k++) for(R i = 1; i <= n; i++) for(R j = 1; j <= n; j++)
	f[i][j] |= f[i][k] & f[k][j]

由于是 bool 值,可以 bitset 优化一下。

bitset<N>f[N];
for(R k = 1; k <= n; k++) for(R i = 1; i <= n; i++) if(k != i && f[i][k]) f[i] |= f[k];

还可以先缩点再 bitset 优化拓扑排序,复杂度 \(\frac {nm} {w}\)

当然和可以使用经典的 bitset 分块,也就是分成几块分别做。

Dilworth定理:最大反链等于最小链覆盖

证明方法一:归纳

link 挺厉害的证明,取出所有交点的最大值构成一个反链这个操作根本学不来。

证明方法二:构造性证明:

设最小链覆盖需要 \(n\) 个链,那么最大反链的大小不会超过 \(n\) , 因为每条链最多选择一个元素。

构造一个大小为 \(n\) 的反链,一开始我想直接构造,尝试了半天都不对,后来向大佬学习了结合网络流的构造方法。

二分图知识可以知道 DAG 的可相交最小路径覆盖是先传递闭包,再转化成二分图,之后 DAG 的最小链覆盖= \(|V|-\) 转化后二分图的最大匹配。

又因为转化后二分图的独立集肯定是原二分图的反链(因为已经传递闭包过了,二分图中独立集互相不可到达,故在 DAG 中必定也互相不可到达),又因为证明了最大独立集=\(|V|-\) 最大匹配。

所以 偏序集的最小链覆盖=最大反链。

链接内的证明全都是构造性证明(有构造方法),故此证明也是。

Dilworth对偶定理:最大链等于最小反链覆盖

证明: 和原定理证明一样,取原图关于完全二分图的补集即可。

Dilworth定理配合鸽巢定理的推论

集合大小是 \(mn+1\), 则要不有 \(m+1\) 的链,要不有 \(n+1\) 的反链。

若都没有,则最多有 \(m\) 个链,每个链最多 \(n\) 个元素,集合大小最大 \(nm\) .

Dilworth定理在多维偏序中应用

导弹拦截:最小上升子序列覆盖等于最长不升子序列长度。

这是二维的偏序,也就是序列下标和值的笛卡尔积,可比定义为 \(i<j, val_i<val_j\)

那么你要反链,任意一对 \(i,j\) 都需要满足 \(i<j \&val_i\geq val_j\) 或者 \(i>j \& val_i \leq val_j\)

这恰好就是最长不升子序列,举个扩展到三维的例子,定义可比为 \(a_i<a_j \& b_i < b_j \& c_i < c_j\)

那么,反链内的任意两个元素 \((i,j)\) 不能有 \(a_i<a_j \& b_i < b_j \& c_i < c_j\) 或者 \(a_i>a_j \& b_i > b_j \& c_i > c_j\)

本质是对笛卡尔积的理解了。

总结,一种证明至多至少的方式:先证明一个界是 \(x\),在构造另一各界是 \(x\) 的一种方案。

Vizing 定理,图着色相关

点着色

给每个点染色使得没有一条边两边的颜色相同,也就是独立集划分。

这部分并没有什么优秀的算法,只有近似算法,可以证明上界是 \(max(deg)+1\)

给出一个把点按度数从大到小排序之后颜色数最多是 \(\displaystyle max_{i=1}^n min\{deg(v_i)+1, i\}\)

Welsh—Powell 算法

就是把剩下的点按度数从大到小排序,然后把第一个点染成当前染色次数的染色 \(i\)

然后从前往后贪心,如果当前点染成 \(i\) 不冲突,那么就把他染成这个颜色,然后删掉。

最后就得到了一组染色,就是这个算法得到的结果,上界是\(\displaystyle max_{i=1}^n min\{deg(v_i)+1, i\}\)

边着色

给每条边染上色使得没有两条共端点的边颜色相同。

Vizing 定理:

  • 对于任意一张简单图最大度数是 \(mx_{deg}\) , 最少需要 \(mx_{deg}/mx_{deg+1}\) 个颜色把整张图边染色。

其中第一类称为 一类图,第二类称为二类图,没有什么好的办法判断一张图是第一类还是第二类,但绝大多数图都是第一类。

最大度数 \(\geq\) 7, 肯定是第一类图,二分图是第一类图,至于证明,一般图不会证。

二分图的 Vizing 定理构造性证明

枚举每一条边,找到 \(f,t\) 最小的没使用过的颜色 \(mn_f, mn_t\), 如果 \(mn_f==mn_t\) 直接染上这种颜色。

否则假设 \(mn_f<mn_t\), 那么考虑把 \(t\)\(mn_f\) 的边改成 \(mn_t\)

如果对 \(t\) 的连边有影响,就不断递归找下去,找出一条增广路,由于找的是最小的没使用过的颜色,一定不会出环。

着色计数

一张无向图 \(G(V,E)\) 用小于等于 \(k\) 个颜色点着色的方案数是 \(\displaystyle \sum_{S \subseteq E} (-1)^{|S|} k^{c(G(S))}\)

\(G(S)\) 代表只保留 \(S\) 集合的边的图, \(c(G)\) 代表 \(G\) 的联通分量个数,证明考虑容斥枚举不合法的边。

当然还可以使用枚举联通块划分进而枚举子集的经典优化, ABC236 Ex 和下面3个题都是这个套路,同时这个是求 “满足某种限制下 ... 互不相同的方案数”的一大法宝。

着色计数-小练习!

1.计算一个 \(n\) 个点的环用至多 \(k\) 色染色的方案数

当然可以去 Dp, 这里利用上述的公式进行推导, 因为 \(<n\) 条边的时候图一定不连通,所以联通块=点数-边数

\[\sum_{S\subseteq E} (-1)^{|S|} k^{c(G(S))}=\sum_{i=0}^{n-1}(-1)^i\binom{n}{i} k^{n-i}+(-1)^n*k \]

\[=\sum_{i=0}^n\binom{n}{i} (-1)^i k^{n-i} -(-1)^n +(-1)^n*k=(k-1)^n+(-1)^n*(k-1) \]

2.计算一个 \(n\) 个点的,包含一个长为 \(a\) 的环的基环树用至多 \(k\) 色染色的方案数

\[\sum_{S\subseteq E} (-1)^{|S|} k^{c(G(S))}=\sum_{ circle \subseteq S} (-1)^{|S|} k^{c(G(S))}+\sum_{ circle\not \subseteq S} (-1)^{|S|} k^{c(G(S))} \]

第一部分必定包含环,第二部分必定不包含环。

\[= \sum_{i=0}^{n-a} (-1)^{a+i}\binom{n-a}{i}k^{n-a+1-i}+ \sum_{i=0}^{a-1}\sum_{j=0}^{n-a}(-1)^{i+j} \binom{n-a}{j}\binom{a}{i} k^{n-i-j} \]

\[=(-1)^ak\sum_{i=0}^{n-a} (-1)^{i}\binom{n-a}{i}k^{n-a-i}+ \sum_{i=0}^{a-1} \binom{a}{i} (-1)^i k^{a-i} \sum_{j=0}^{n-a} (-1)^j\binom{n-a}{j} k^{n-a-j} \]

\[=(-1)^ak(k-1)^{n-a}+ (k-1)^{n-a}(\sum_{i=0}^{a} \binom{a}{i} (-1)^{i} k^{a-i} -(-1)^a) \]

\[=(-1)^ak(k-1)^{n-a}+ (k-1)^{n-a}((k-1)^a-(-1)^a) \]

虽然这是最基本的图染色计算公式,但是还是可以考虑用它去扩展到特殊情况

无环定向数

\(X(G,k)\) 为图 \(G\) 的色多项式,那么把 \(t\) 带入 \(X(G,k)\) 得到的就是用 \(\leq t\) 种颜色给 \(G\) 点染色的方案数。

色多项式是一个 \(n\) 次的多项式, 因为 \(X(G,k)=\sum_{k=0}^n \binom x k g(k)\) \(g(k)\) 是划分成 \(k\) 个独立集的方案数。

  • 定理:无向图 \(G\) 的无环定向数 (给每一条边定向,使得有向图是一个 DAG) 为 \(X(G,-1)\)

一般图来说,我们可以求出色多项式的 \(n\) 个点值,然后带入 \(-1\) 即可,特殊图我们有表达式之后不用顾虑组合意义直接带入 -1 即可。

定理证明,首先第二维是 \(-1\) 的原因是我们先考虑 \(E(G)=0\) ,那么 \(X(G,k)=k^n\)
\(X(G,-1)=(-1)^n, X(G,-1)*(-1)^n=1\) 符合没有边的图的无环定向方案数 \(=1\)

然后考虑归纳,色多项式有一个递推式 \(X(G,k)=X(G-e,k)-X(G\cdot e,k)\) \(G\cdot e\) 代表的是把 \(e\) 这条边缩成一个点, \(e\) 两边的点删除,缩掉的点向 \(e\) 两边的点的并集连边的图。

这个递推式显然是正确的, 去掉 \(e\) 之后的染色方案可能在有 \(e\) 的时候不合法,原因是 \(e_f\)\(e_t\) 颜色相同,每一种这样的情况,我们把 \(e_f,e_t\) 缩起来之后都是一个合法的染色方案 (钦定颜色相同,缩成一个点)。

然后考虑在边集上面归纳, \(X(G,-1)*(-1)^n=(X(G-e,-1)-X(G\cdot e, -1))*(-1)^n=X(G-e,-1)*(-1)^n+X(G\cdot e, -1)*(-1)^{n-1}\) 我们只需要证明 \(G\) 的无环定向方案数是 \(G-e\) 的方案数和 \(G\cdot e\) 的方案数之和即可。

考虑 \(G-e\) 的每一种拓扑序,我们把 \(e\) 两端 \(u,v\) 中拓扑序小的连向拓扑序大的,肯定对 \(G\) 是一种合法方案。
还有一种可能性就是 \(G-e\)\(u,v\) 没有路径,意味着这条边可以随便连, \(u,v\) 没有路径,我们把 \(u,v\) 缩起来,肯定无环,所以,每一种 \(u,v\) 之间缩起来且无环的图对应一个 \(G-e\)\(u,v\) 没有路径的图,这种路径在 \(G-e, G\cdot e\) 中被我们个计算一遍,所以是正确的。

Hall定理

设二分图中集合 \(S\) 的邻域 \(N(S)\) 为他连向的边在另一个集合内有多少点。

Hall定理 :一个二分图,两部为 \(X,Y, |X| \leq |Y|\),存在一个大小为 \(|X|\) 的匹配,当且仅当 \(\forall S \subseteq X\), 有 \(|N(S)| \geq |S|\)

证明:

必要性: 如果存在一个 \(S\) 使其不成立,那么 \(S\) 集合内的所有点都无法全部匹配,原图自然无法全部匹配。

充分性:考虑直接构造出来最大匹配,使用数学归纳法,现在假设所有 \(< n\) 的都已经成立。

找到最小的 \(S\), 其 \(N(S)=S\), 然后把他全部连上(由归纳知他们有完美匹配),然后规约到更小规模的问题。

假设此时不存在 \(N(S)=S\), 那么直接找到任意一个点,随意连一条边然后把它删掉,肯定不会因为他删掉出现不符合 hall 定理的情况,因为所有人都大于,规约到 \(n-1\) 的问题。

推论1:一个二分图,两部为 \(X,Y, |X| \leq |Y|\),存在一个大小为 \(|X|-t\) 的匹配,当且仅当 \(\forall S \subseteq X\), 有 \(|N(S)| \geq |S| - t\) 证明和 hall 定理基本一样

推论2:对于多重匹配, \(u\) 可以匹配 \(W_u\) 次, 那直接把 \(u\) 拆成 \(W_u\) 个点, 转成二分图,即可使用 Hall定理

推论的过程中,我们把 \(u\) 拆成的点连出的边是相同的,所以实际上我们只需要关注每个点选择他所有点时候符不符合即可(因为不选他所有点不会让 \(|N(S)|\) 变小,只会让 \(|S|\) 变小。

所以,可以得到二分图存在带权完美匹配 (\(\sum W\) 小的一侧全部匹配) 的条件是 \(\forall S \subseteq X\), 有 \(W_{N(S)} \geq W_{S}\)

推论3:一个 k 正则二分图,左右点数相等,必存在完美匹配

一个无向图,每个点度数都是 \(k\) ,则称这个图为 k-正则图。

假设存在一个集合 \(S\), \(|N(S)|<|S|\), 由于 \(|S|\)\(|N(S)|\) 连了 \(|S|*k\) 条边,所以 \(N(S)\) 至少有 \(|S|*k\) 条边,但是 \(N(S)\) 只有 \(N(S)*k\) 条边,与假设矛盾,故推论成立。

推论4:一个二分图,左侧的点至少和 \(k\) 个点连边,右侧的点至多和 \(k\) 个点连边,则存在完美匹配

左侧一个大小为 \(|S|\) 的子集,右侧有 \(|T|<|S|\), 左侧连了 \(\geq |S|*k\), 然后右侧有 $ \leq |T|*k$ 条边,然后和 3 一样。

关键 推论5:二分图的最大匹配为 \(|X|-max(|S|-|N(S)|)\), 其中 \(S\subseteq X\) (X 是较小的一部)

其实说是关键也没什么,可以直接根据推论1证明,既然有 \(|X|-t\) 的要求是那个,我就找到最大的破坏要求的数,然后把要求调整,这样就肯定附和条件了。

还有一个比较启发的证明,同样可以用来证明 hall 定理。

枚举一个点集 \(S\), 然后割掉 \(S\) 的补集 \(X-S\), 此时要想成为原图的一组割,还要割掉 \(N(S)\), 把柿子转化发现时 \(\min(X-|S|+|N(S)|)\), 就是割取最小值,即最小割,也就是最大匹配。

证明 hall 定理那个东西和 \(n\) 取 min 即可。

网络流-最大流/最小割

正确性

最大流的算法基于不断寻找增广路然后增广,其中关键的一点就是不存在增广路的时候一定是最大流

为证明这个,我们先给出一个关键的定理

最大流最小割定理

一个网络的最大流=最小割,割的定义是一组边集,断掉他们之后 \(S\), \(T\) 不连通,一般割也可以代指这个边集的容量之和。

我们定义一个流 \(f\) 关于一个割集 \(g\) 的流量 \(G_f(g)\) 代表这个流流过这组割集的流量。

可以证明,对于一个固定的流,任意一个割集 \(g'\)\(G_f(g')=G_f(g)=|f|, |f|\) 代表这个流的流量。

因为流量守恒,初始假设 \(S\) 和剩下的所有点形成两个集合,他们之间割集的流量肯定是 \(|f|\), 你接着往 \(S\) 所在的集合加入任意一个不是 \(T\) 的点,不会改变 \(S\) 所在集合流出去了多少流量,因为每个不是 \(S\) 的点都只流出去 \(0\) 的流量。

所以,我们可以得到,对于任意一个流,都有任意一组割的容量 \(\geq\) 这个流的流量,也就是任意一个流 \(\leq\) 最小割。

至此,我们引出最大流最小割定理

  1. \(f\)\(G\) 的一个最大流。
  2. \(f\)\(G\) 中不存在增广路。
  3. \(|f| = G_f(g)\), \(g\) 是该网络任意一个切割。

这三个条件是等价的。

\(1 \Rightarrow 2\), 若存在增广路,则一定不是最大流

\(2 \Rightarrow 3\), 由于不存在增广路,所以 \(G\) 中没有 \(S\)\(T\) 的路径,所以一个切割的流量=容量,否则若有一条在割集中的边流量不等于容量,则存在一条 \(S\)\(T\) 的路径,与不存在增广路矛盾。

\(3 \Rightarrow 1\), 由于任意一个流的流量 \(\leq\) 最小割,存在一个割等于流量,隐含着他是最大流。

复杂度

/

EK 复杂度证明

EK 采用从短到长依次确定增广路的方法,可以证明增广路不会变短,一次寻找增广路并增广的时间显然是 \(O(m)\) , 我们只需要证明最多 \(nm\) 次增广。

先证明增广路不会变短,我们只需要证明 \(f \rightarrow f'\) 任意一个点的 \(dis \leq dis'\)

假设从 \(f \rightarrow f'\) 的过程中增广路变短了,那么假设 \(u\)\(dis'\) 最小的 \(dis'\) 变小的点。

首先,假设 \(v\)\(dis'_u\) 最短路上的前驱,那么 \((u,v)\) 这条边如果不是 \(f \rightarrow f'\) 这次增广出现的,那么一定不合法,因为 \(u\) 是最小的 \(dis'\) 变小的点,如果合法那么 \(dis'_v\) 肯定也会变小。

其次,如果 \((u,v)\) 是新出现的,那么 \(v\) 本来是 \(u\) 的一个后继,现在变成了 \(u\) 的前驱,由于我们找的是最短路,所以 \(dis'_u\) 至少要增大 \(2\)

接着证明最多 \(nm\) 次增广。

我们每进行一次增广,肯定会导致一条边 \((u,v)\) 消失,如果这条边再次出现,那么肯定是从 \(v\)\(u\) 的一条增广路。

由于我们找的是最短路, 那么,消失的时候 \(dis_u=dis_v-1\), 出现的时候 \(dis_u=dis_v+1\), 这么一折腾, \(dis_u\) 至少加 \(2\) , 由于 \(dis\) 不减,所以每个点的 \(dis\) 最多增加 \(n/2\) 次,一共 \(m\) 条边,每条边最多消失 \(n/2\) 次,故总增广次数是 \(nm\) 的。

Dinic 复杂度证明

在证明 EK 的过程中我们可以发现,增广长都为 \(dis\) 的路,可能带来长度为 \(dis+2\) 的路,但不能带来 \(dis\) 的路。

也就是,如果我们能一次增广所有长度为 \(k\) 的路,那么我们只会增广 \(n/2\) 次。

Dinic 一次增广复杂度是 \(O(nm)\) 的,因为一共 \(m\) 条边,每条边最多在一条 \(O(n)\) 便利路径时消失一次。

一些特殊的复杂度

  • 若是二分图,复杂度 \(\sqrt n m\)
  • 若容量全是 \(1\), 复杂度 $ \min(\sqrt m m, n^{2/3}m)$ 。
  • 单位图(unit graph) 是指,所有的边的容量都是整数,且每一个不是 \(s\)\(t\) 的点,要么出度为 1,连出去的边容量为 1,要么入度为 1,连进来的边容量为 1, 单位图上复杂度和二分图相同。

DAG最小路径覆盖

最大权闭合子图

给定一个 DAG, 每个点有一个点权,选出一个子图,使得这个子图内任意一个点连出的边都在这个子图内。

观察性质,如果所有点点权都是正数,那么肯定选择所有点。

问题就在于一些点权为负数的点,这启发我们对点权正负分类讨论。

我们选取一个点权是正数的点,就要被迫选取所有他连向的点权为负数的点。

我们用 \(S\) 向所有点权为正数的点连 点权的边,把所有点权为负数的点向 \(T\) 连点权的绝对值。

原图的边设置成正无穷,那么所有点权为正数的边-最小割就是答案。

考虑不选择了一个正数边,就相当于直接把他割掉。

选择,就相当于必须割掉他连向的负点的边,以及负点连向的负点的边。

上下界网络流

无源汇上下界可行流

无源汇流 : 满足流量平衡即可,大概是几个“涡流”。
上下界 :每条边需要满足其流量在 \([L,R]\) 内。

先让每条边流其下界,那么现在的网络就只有下界了,但是他现在可能是不平衡的。

我们的目的就是添加一个附加的流,并且不超过 \(R\),使得网络平衡。

我们统计每个点流入-流出= \(M_i\)

\(M_i=0\) ,则说明他已经平衡。

\(M_i>0\) ,则说明流进来多了,我们想让他流走,那么就用超级原点 \(S'\) 想他连 \(M_i\) 的边,实际意义是原点把他多余的流量推走。

\(M_i<0\) ,同理用它向 \(T'\)\(-M_i\) 的边,代表需要有 \(M_i\) 的流量流进来。

所以我们如上建图之后,在 \(S',T'\) 之间跑一个最大流,如果每条边都满流就说明存在一个调整方案,即存在一个可行流。

code

有源汇上下界可行流

\(T\)\(S\) 建一条 \([0,\infty]\) 的边,然后他就变成了无源汇。

如果有解,那么流量就恰好是这条边的流量(电池内部负极流向正极, 注意我们要求的源汇之间的流量并不是增广的流量,而是电池边的流量!

有源汇上下界最大流

先得到可行流,然后去掉超级源汇,直接在 \(S,T\) 跑一次最大流即可得到,答案是可行流流量+最大流流量。

因为可行流已经让流量守恒,跑最大流不会改变流量守恒的性质,所以可以直接跑一下去调整。

code

有源汇上下界最小流

先可行流,去掉电池边,然后从 \(T\)\(S\) 跑,答案是可行流流量-最大流流量。

code

最小割性质,最小割树

最小割必须边和可行边:建出残量网络后缩点成 DAG 去判断,具体参考 ix35

最大匹配必须边和可行边:建出残量网络后缩点成 DAG 去判断,可行就是在当前匹配里或这条边两端在一个 SCC 里,必须就是在当前匹配里且这条边两端不在一个 SCC 里,具体参考 ix35

最大匹配必须点和可行点:可行点仿照上栗,如果是非匹配点且度数不为0,一定可以找到一条半增广路。

必须点:是匹配点并且匹配边另一侧的点连向的点都是匹配点,对应到图中,即和S不在同一个SCC里面。

  • 网络流中可以存在若干可以增广的环,增广他们并不会改变流量但会改变流结构。
  • 残量网络上的 SCC 在网络流分析方面是一个利器。

网络流-费用流

特殊的费用流模型

最大费用任意流 & 正费用最大流

性质:每次寻找的增广路长度(费用)是单调不降的,EK复杂度已经证明过了。

也就是,我们得到的总费用具有凸性,具体来说,这个右下凸包。

利用这个,我们来可以解决一些特殊的需求

比如这两类,我们都是要找最长路去增广,第一个费用负了就不增广。

第二个只要费用 > 0 就一直增广,注意最后一个增广可能不增广一条满流。

带有负环的费用流问题

强制所有负权边满流,然后流量不守恒,但已经没了负环。

强制满流的代码实现
inline void link(int f, int t, int w, int c){
    if(c >= 0) add(f, t, w, c), add(t, f, 0, -c);
    else{
        tot[t] += w, tot[f] -= w, ansc += w * c;
        add(f, t, 0, c), add(t, f, w, -c);
    }
}	// 注意不要忘记把费用加到 ans 里面。

和上下界一样的手法,建超级源汇去处理,跑最小费用最大流, 然后为了最大流,还需要去掉电池边,再跑一遍真正源汇的最小费用最大流即可。

注意我们要求的源汇之间的流量并不是增广的流量,而是电池边的流量!

code

有源汇上下界最小费用可行流

最大流变成最小费用最大流即可,一开始我有一个疑问,存不存在费用的增广路,现在看来他不是问题,因为肯定不存在。

如果存在费用的增广路并且不会改变流量,那么最小费用最大流肯定回去跑它,而不会留下来, code

有源汇上下界最大费用可行流

找最长路即可,但是可能出现负环,需要配合负环费用流。

网络流-模拟费用流

posted @ 2022-06-15 12:10  Soresen  阅读(229)  评论(2编辑  收藏  举报