最大流
上下界网络流
对于该问题的图 (G') ,对于每条边 ((u,v)in E) ,有两个容量限制 (c_l(u,v)) 和 (c_u(u,v)) 。可行流必须满足:
无源汇上下界可行流
没有源汇的流即循环流,每个点都满足流量守恒。
这类问题一般采取 " 调整策略 " ,也就是先找一个符合部分限制的流,然后经过调整使得它符合所有限制。
那么不难想到先让每条边的流达到下界,此时每条边的剩余容量 (c'(u,v)=c_u(u,v)-c_l(u,v)) 。
但是每个点的流量可能不守恒,我们需要进行调整,根据流的加法,这也可以描述为加上一个可行流 (delta) 。
对于点 (u) ,记 (I_u) 为目前进入 (u) 的流量, (O_u) 为从 (u) 出发的流量。
那么显然有: (I_u=sum_{(v,u)in E}c_l(v,u),O_u=sum_{(u,v)in E}c_l(u,v)) 。
此时如果 (I_u=O_u) ,那么此时它已经守恒,而 (delta) 本身也是守恒的,所以这样的点我们不需要管它。
那么剩下的点,我们可以认为是 (I_u>O_u) 的点需要流出更多,而 (I_u<O_u) 的点需要流入更多。
不妨先给 (I_u<O_u) 的点以 (O_u-I_u) 的流,那么它就要去找接流的点,也就是 (I_u>O_u) 的点。
至于 " 给流 " 的想法,自然可以通过连接源点实现, " 接流 " 自然可以通过连接汇点实现。
需要注意的是,由于真实的图中流不从汇点流入,而是从其它点流过来,所以新图的边应该反着建,就像是从 (I_u<O_u) 的点出发,倒着去找 (I_u>O_u) 的点。
因此可以考虑构建标准网络 (G_s) ,其中对于 ((v,u)in E) ,满足 (c(u,v)=c_u(v,u)-c_l(v,u)) 。
而对于 (I_u<O_u) 的点,连接 (S ightarrow u) ,容量为 (O_u-I_u) 。
对于 (O_u<I_u) 的点,连接 (u ightarrow T) ,容量为 (I_u-O_u) 。
在 (G_s) 上面跑最大流,如果 (S) 的出边均满流, (T) 的入边均满流(简称 " 满流 " ),就说明原图存在可行流。
这个过程类似于基于一般图的边的二分图多重匹配问题。
当然,把所有的边都反过来,并且交换 (S) 和 (T) ,就变成了网上常见的做法。
关于正确性,我们只需要证明 (p=) " (G_s) 上满流 " (Leftrightarrow) (q=) " 原图存在可行流 "。
首先 (pRightarrow q) 是很好证明的,可以直接模仿上面的思路进行构造。
而 (qRightarrow p) ,我们可以也构造。
我们找出原图的可行流 (f) ,构造 (G_s) 上对应的流 (f') :
对于边 ((v,u)in E,f'(u,v)=f(v,u)-c_l(v,u)) 。
考虑一个 (I_u<O_u) 的点,(S) 与它有边,容量为 (O_u-I_u) 。此时我们安排 (f'(S,u)=O_u-I_u) 。
同理,对于 (I_u>O_u) 的点,它与 (T) 有边,容量为 (I_u-O_u) 。此时我们安排 (f'(u,T)=I_u-O_u) 。
首先 (f') 显然满足容量限制,我们只需要看一下它是不是流量守恒的。
在 (f) 上有:
那么对于 (I_u=O_u) 的点,在 (G_s) 上必然流量守恒,不再赘述。
对于 (I_u<O_u) :
而对于 (I_u>O_u) 也有类似成立。因此我们构造的 (f') 是 (G_s) 的可行流,且在 (G_s) 上满流。
例题一道[HDU4940]Destroy Transportation system
......和题解通道。
有源汇上下界可行流
考虑一下源汇与普通点的区别。事实上只有唯一的区别,即源汇流量不守恒,且源点多流出的恰好等于汇点多流入的。
那么我们可以尝试将汇点多的流引到源点,这样就守恒了。
实际操作就是在原图 (G) 中连接一条 (t ightarrow s) ,下界为 (0) ,上界为 (+infty) 。
下文我们如果不是特殊提到,否则 (E) 中不包含这条边。
有源汇上下界最大流
由于现在有两个源汇,所以我们称 (G) 上的源汇为 (s,t) ,构造的 (G_s) 上的为 (s_s,t_s) 。
为了避免奇奇怪怪的错误,我们这里的 (G_s) 相对于上述的版本,已经将所有边反向并且交换了 (s_s) 和 (t_s),即它满足你在网上可以看到的其它版本的构造方法:
- 如果 ((u,v)in E) ,连接 (u ightarrow v) ,容量为 (c_u(u,v)-c_l(u,v)) 。
- 如果 (I_u>O_u) ,连接 (s_s ightarrow u) ,容量为 (I_u-O_u) 。
- 如果 (I_u<O_u) ,连接 (u ightarrow t_s) ,容量为 (O_u-I_u) 。
有一个很直观的做法:我们先在 (G_s) 上,跑一组 (s_s ightarrow t_s) 的最大流 (f_0),判断是否有可行流;接着再在 (G_s) 的残余网络上,跑一组 (s ightarrow t) 的最大流 (f_{s ightarrow t}) 。那么原图的最大流就是 (f_0+f_{s ightarrow t}) 。
感性理解, (f_0) 必然可以反向构造出一个原图的可行流 (f_0') ,而 (f_{s ightarrow t}) 也可以构造出一个增广流 (f_{s ightarrow t}') ,此时 (G_{f_0'+f_{s ightarrow t}'}) 上是没有增广路的。
事实上这个做法是完全正确的,我们下面将给出证明:
以下均认为 (G) 是存在可行流的。
首先,原图的一个可行流和 (G_s) 上的一个最大流是完全等价的。如果你对这一点还不太熟悉,那么请参考 无源汇上下界可行流 部分。
于是我们只需要证明 (f_0+f_{s ightarrow t}) 仍然对应 (G_s) 上的一个最大流,并且 (f_0+f_{s ightarrow t}) 对应的 (G) 上的流不存在增广路。
证明第一步,我们先证明 (f_0+f_{s ightarrow t}) 对应 (G_s) 上的一个流。
性质一:容量限制
由于 (s_s) 只有出边, (t_s) 只有入边,那么可以知道, (f_{s ightarrow t}(u,v) ot=0Leftrightarrow (u,v)in E) 。
对于 ((u,v)in E) 的边,由于 (f_{s ightarrow t}) 是在 (G_{s_{f_0}}) 上面跑出来的,所以它们满足容量限制(如果你不明白,可以参考性质 5:流的加法)。
对于其它边, (f_{s ightarrow t}) 不会影响,因此它们也满足容量限制。
性质二:流量守恒
不难发现,在 (G_s) 中,对于 (uin V-{s,t,s_s,t_s}) , (u) 仍然满足流量守恒(如果你不明白,可以参考性质 5:流的加法)。
而 (s,t) 在 (f_0) 上守恒,而在 (f_{s ightarrow t}) 上不守恒。不过,我们还有一条 (t ightarrow s) 的无穷边,因此我们可以通过这条边发送 (|f_{s ightarrow t}|) 的流量,从而使得 (s,t) 流量守恒。而 (t ightarrow s) 容量为 (+infty) ,因此不会超过容量限制。
所以 (f_0+f_{s ightarrow t}) 仍然对应 (G_s) 上的一个流。
考虑它是否最大——这是显然的,因为 (f_0) 已经 (G_s) 上的最大流,而 (f_{s ightarrow t}) 并不会影响到 (s_s) 的出边和 (t_s) 的入边。
因此 (f_0+f_{s ightarrow t}) 仍然对应 (G_s) 上的一个最大流。
证明第二步,我们证明 (f_0+f_{s ightarrow t}) 对应的 (G) 上的流不存在增广路。
首先构造 (G) 上的流 (f') 。对于边 ((u,v)in E) , (f'(u,v)=f_0(u,v)+f_{s ightarrow t}(u,v)+c_l(u,v)) 。
如果此时 (G_{f'}) 上存在一条增广路,那么对于其中的每一条边都有 (f_0(u,v)+f_{s ightarrow t}(u,v)=f'(u,v)-c_l(u,v)) ,此时一定有左边 (< c_u(u,v)-c_l(u,v)) 。因而 (s ightarrow t) 上也有一条增广路, (f_{s ightarrow t}) 就不是题设的最大流。
实际操作很显然,就不说了
笔者被实际操作打败了
实际操作的时候, (f_0) 应该取到 (s ightarrow t) 的流量——可行流的流量,可以直接查 (t ightarrow s) 这条边的流量。而 (f_{s ightarrow t}) 则可以直接用算法得出的流量。
有源汇上下界最小流
笔者拒绝写不会的证明,并且向你扔了一个结论
沿用上一个部分的内容。我们现在已经得到了 (f_0) 和 (f_{s ightarrow t}) 。现在我们拆掉 ((t,s)) 这条边,并跑一个 (t ightarrow s) 的最大流 (f_{t ightarrow s}) 。答案就是 (|f_0|_{s ightarrow t}+|f_{s ightarrow t}|-|f_{t ightarrow s}|) 。
混合图欧拉回路
咕咕咕
最小割
最大带权闭合子图
这个问题基于一个有向图 (G=(V,E)) ,对于所有的 (uin V) ,都有一个实数的权值 (w_u) 。
它的一个闭合子图(实际上是一个子集)被定义为 (V') ,满足:
- (V'subseteq V)
- 对于任意的 (uin V',vin V) ,如果在 (G) 上, (u) 可以到达 (v) ,那么 (vin V') 。
并定义一个闭合子图的权为 (sum_{uin V'}w_u) 。
我们将其转化为最小割问题:
首先我们找出每个点的两种情况:属于 (V') 或者不属于 (V') ,其中前者对应在割中属于 (S) ,后者对应在割中属于 (T) 。
注意到我们的最小割计算的是代价,所以对于 (u(w_uge0)) ,它属于 (T) 就会带来 (w_u) 的代价,因此需要连接 (s ightarrow u) ,容量为 (w_u);而对于 (u(w_u<0)) ,它属于 (S) 就会带来 (-w_u) 的代价,因此需要连接 (t ightarrow u) ,容量为 (w_u) 。
考虑 (E) 中的边的限制。对于 ((u,v)in E) ,如果 (uin S) 而 (vin T) ,这就是不合法的情况——即,我们需要在这种情况发生时,让 (s) 和 (t) 连通,于是不难想到连接 (u ightarrow v) ,容量为 (+infty) 。
答案就是:
设构建的网络为 (G_n=(V_n,E_n)) 。
简单证明一下:
-
定义简单割为不包含 (+infty) 的割边的割。
那么网络上的最小割一定是简单割。
证明
将 (s) 的所有出边割掉,我们已经得到了一个割 ([{s},V_n-{s}]) ,而其中并不包含 (+infty) 的割边,且必然比包含 (+infty) 的割边的割的容量小。
又因为最小割是容量最小的割,那么它的容量一定小于构造的割,所以最小割一定是简单割。
-
网络上的一个简单割与原图上的一个闭合子图一一对应。
证明
-
证明:简单割 ( ightarrow) 闭合子图
找出一组简单割 ([S,T]) ,此时我们让 (V'=S-{s}) ,显然满足 (V'subseteq V) 的条件。
反证,假设有 (uin V',vin V-V') ,而在 (G) 上 (u) 可以到达 (v) ,还原到 (G_n) 上,必然有 (uin S) 而 (vin T) 。
由于简单割的割边一定不包含 (+infty) 的割边,因此 (u ightarrow v) 的路径上的边一定没有被割,因此 (u) 和 (v) 应该属于同一个集合,矛盾。
因此简单割一定对应了一个闭合子图。
-
证明:闭合子图 ( ightarrow) 简单割
对于闭合子图 (V') ,我们构造割 ([S=V'cup {s},T=Vsetminus V'cup{t}]) 。
考虑割是否包含 (+infty) 的割边。假设有,不妨设边为 (u ightarrow v) ,那么 (uin S) 而 (vin T) 。由于边权为 (+infty) ,所以 ((u,v)in E) ,这与 (V') 是闭合子图矛盾,所以 ([S,T]) 是简单割。
因此一个闭合子图一定对应了一个简单割。
这一结论为下面的内容奠定了基础。
-
-
" 答案 " 就是最大权闭合子图的权值和。
证明
对于任何一个简单割 ([S,T]) 有:
[egin{aligned} &sum_{uin V}w_u[w_uge0]-c(S,T)\ =&sum_{uin V}w_u[w_uge0]-left(sum_{uin S-{s}}(-w_u)[w_u<0]+sum_{uin T-{t}}w_u[w_uge0] ight)\ =&sum_{uin S-{s}}w_u end{aligned} ]而根据我们的证明方式, (S-{s}) 就是一个闭合子图。因而一个割的容量与一个闭合子图的权是对应的。
注意到上式中 (sum_{uin V}w_u[w_uge 0]) 是定值,由于我们证明了割集合闭合子图集是等价的,因此最小化 (c(S,T)) 即可最大化权。
最大带权子图
对于一个无向图 (G=(V,E)) ,每个点有一个正实数权 (w) ,每条边有一个正实数权 (W) 。
定义一个子图 (G'=(V',E')) ,满足 (V'subseteq V,E'subseteq E) ,且 (forall (u,v)in E',uin V',vin V') 。
定义它的权为 (sum_{ein E'}W_{e}-sum_{uin V'}w_u) 。
求无向图中的最大权的子图。
比较显然的做法是:对于每条边建立点,对每个点再建立点。如果一条边 ((u,v)) 被选择,就说明 (u,v) 都必须被选择,转化成最大权闭合子图问题。
上面这种做法不够有些,点总共有 (n+m+2) 个。注意到由于 (W>0) ,所以当 (V') 确定的时候,我们必然尽量多选边,因此 (G') 一定是 (V') 生成的诱导子图。此时有 (E'=Ecap (V' imes V')) 。
直接找出 (E') 不太方便,我们考虑减去不在 (E') 中的边;那么此时的边权就是:
设 (d_u=sum_{(u,v)in E}W_{(u,v)}) ,则有:
后半部分可以类比网络流中的 " 割的容量 " 。不难想到使用最小割:
- 对于 (u) ,我们认为 (uin S) 表示 (u) 被选中, (uin T) 表示 (u) 没被选中;
- 选择 (u) 会带来 (d_u-2w_u) 的代价,这个连接见仁见智。
- 如果 ((u,v)in E) ,并且 (uin S,vin T) ,我们需要计算它的代价。因此连接 (uleftrightarrow v) ,容量为 (W_{(u,v)}) 。