网络流模型基础

最大流

上下界网络流

对于该问题的图 \(G'\) ,对于每条边 \((u,v)\in E\) ,有两个容量限制 \(c_l(u,v)\)\(c_u(u,v)\) 。可行流必须满足:

\[\forall (u,v)\in E,c_l(u,v)\le f(u,v)\le 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\rightarrow u\) ,容量为 \(O_u-I_u\)

对于 \(O_u<I_u\) 的点,连接 \(u\rightarrow T\) ,容量为 \(I_u-O_u\)

\(G_s\) 上面跑最大流,如果 \(S\) 的出边均满流, \(T\) 的入边均满流(简称 " 满流 " ),就说明原图存在可行流。

这个过程类似于基于一般图的边的二分图多重匹配问题

当然,把所有的边都反过来,并且交换 \(S\)\(T\) ,就变成了网上常见的做法。


关于正确性,我们只需要证明 \(p=\) " \(G_s\) 上满流 " \(\Leftrightarrow\) \(q=\) " 原图存在可行流 "

首先 \(p\Rightarrow q\) 是很好证明的,可以直接模仿上面的思路进行构造。

\(q\Rightarrow 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\) 上有:

\[\forall u,\sum_{(v,u)\in E}f(v,u)=\sum_{(u,w)\in E}f(u,w) \]

那么对于 \(I_u=O_u\) 的点,在 \(G_s\) 上必然流量守恒,不再赘述。

对于 \(I_u<O_u\)

\[\begin{aligned}&\left(\sum_{(u,w)\in E}f(u,w)-c_l(u,w)\right)+O_u-I_u\\-&\left(\sum_{(v,u)\in E}f(v,u)-c_l(v,u)\right)\\=&\sum_{(v,u)\in E}c_l(v,u)-\sum_{(u,w)\in E}c_l(u,w)+O_u-I_u\\=&0\end{aligned} \]

而对于 \(I_u>O_u\) 也有类似成立。因此我们构造的 \(f'\)\(G_s\) 的可行流,且在 \(G_s\) 上满流。

例题一道[HDU4940]Destroy Transportation system

......和题解通道

有源汇上下界可行流

考虑一下源汇与普通点的区别。事实上只有唯一的区别,即源汇流量不守恒,且源点多流出的恰好等于汇点多流入的

那么我们可以尝试将汇点多的流引到源点,这样就守恒了。

实际操作就是在原图 \(G\)连接一条 \(t\rightarrow s\) ,下界为 \(0\) ,上界为 \(+\infty\)

下文我们如果不是特殊提到,否则 \(E\) 中不包含这条边。

有源汇上下界最大流

由于现在有两个源汇,所以我们称 \(G\) 上的源汇为 \(s,t\) ,构造的 \(G_s\) 上的为 \(s_s,t_s\)

为了避免奇奇怪怪的错误,我们这里的 \(G_s\) 相对于上述的版本,已经将所有边反向并且交换了 \(s_s\)\(t_s\),即它满足你在网上可以看到的其它版本的构造方法:

  1. 如果 \((u,v)\in E\) ,连接 \(u\rightarrow v\) ,容量为 \(c_u(u,v)-c_l(u,v)\)
  2. 如果 \(I_u>O_u\) ,连接 \(s_s\rightarrow u\) ,容量为 \(I_u-O_u\)
  3. 如果 \(I_u<O_u\) ,连接 \(u\rightarrow t_s\) ,容量为 \(O_u-I_u\)

有一个很直观的做法:我们先在 \(G_s\) 上,跑一组 \(s_s\rightarrow t_s\) 的最大流 \(f_0\),判断是否有可行流;接着再在 \(G_s\) 的残余网络上,跑一组 \(s\rightarrow t\) 的最大流 \(f_{s\rightarrow t}\) 。那么原图的最大流就是 \(f_0+f_{s\rightarrow t}\)

感性理解, \(f_0\) 必然可以反向构造出一个原图的可行流 \(f_0'\) ,而 \(f_{s\rightarrow t}\) 也可以构造出一个增广流 \(f_{s\rightarrow t}'\) ,此时 \(G_{f_0'+f_{s\rightarrow t}'}\) 上是没有增广路的。

事实上这个做法是完全正确的,我们下面将给出证明:


以下均认为 \(G\) 是存在可行流的。

首先,原图的一个可行流和 \(G_s\) 上的一个最大流是完全等价的。如果你对这一点还不太熟悉,那么请参考 无源汇上下界可行流 部分。

于是我们只需要证明 \(f_0+f_{s\rightarrow t}\) 仍然对应 \(G_s\) 上的一个最大流,并且 \(f_0+f_{s\rightarrow t}\) 对应的 \(G\) 上的流不存在增广路。

证明第一步,我们先证明 \(f_0+f_{s\rightarrow t}\) 对应 \(G_s\) 上的一个流。

性质一:容量限制

由于 \(s_s\) 只有出边, \(t_s\) 只有入边,那么可以知道, \(f_{s\rightarrow t}(u,v)\not=0\Leftrightarrow (u,v)\in E\)

对于 \((u,v)\in E\) 的边,由于 \(f_{s\rightarrow t}\) 是在 \(G_{s_{f_0}}\) 上面跑出来的,所以它们满足容量限制(如果你不明白,可以参考性质 5:流的加法)。

对于其它边, \(f_{s\rightarrow t}\) 不会影响,因此它们也满足容量限制。

性质二:流量守恒

不难发现,在 \(G_s\) 中,对于 \(u\in V-\{s,t,s_s,t_s\}\)\(u\) 仍然满足流量守恒(如果你不明白,可以参考性质 5:流的加法)。

\(s,t\)\(f_0\) 上守恒,而在 \(f_{s\rightarrow t}\) 上不守恒。不过,我们还有一条 \(t\rightarrow s\) 的无穷边,因此我们可以通过这条边发送 \(|f_{s\rightarrow t}|\) 的流量,从而使得 \(s,t\) 流量守恒。而 \(t\rightarrow s\) 容量为 \(+\infty\) ,因此不会超过容量限制。

所以 \(f_0+f_{s\rightarrow t}\) 仍然对应 \(G_s\) 上的一个流。

考虑它是否最大——这是显然的,因为 \(f_0\) 已经 \(G_s\) 上的最大流,而 \(f_{s\rightarrow t}\) 并不会影响到 \(s_s\) 的出边和 \(t_s\) 的入边。

因此 \(f_0+f_{s\rightarrow t}\) 仍然对应 \(G_s\) 上的一个最大流

证明第二步,我们证明 \(f_0+f_{s\rightarrow t}\) 对应的 \(G\) 上的流不存在增广路。

首先构造 \(G\) 上的流 \(f'\) 。对于边 \((u,v)\in E\)\(f'(u,v)=f_0(u,v)+f_{s\rightarrow t}(u,v)+c_l(u,v)\)

如果此时 \(G_{f'}\) 上存在一条增广路,那么对于其中的每一条边都有 \(f_0(u,v)+f_{s\rightarrow t}(u,v)=f'(u,v)-c_l(u,v)\) ,此时一定有左边 \(< c_u(u,v)-c_l(u,v)\) 。因而 \(s\rightarrow t\) 上也有一条增广路, \(f_{s\rightarrow t}\) 就不是题设的最大流。


实际操作很显然,就不说了

笔者被实际操作打败了

实际操作的时候, \(f_0\) 应该取到 \(s\rightarrow t\) 的流量——可行流的流量,可以直接查 \(t\rightarrow s\) 这条边的流量。而 \(f_{s\rightarrow t}\) 则可以直接用算法得出的流量。

有源汇上下界最小流

笔者拒绝写不会的证明,并且向你扔了一个结论

沿用上一个部分的内容。我们现在已经得到了 \(f_0\)\(f_{s\rightarrow t}\) 。现在我们拆掉 \((t,s)\) 这条边,并跑一个 \(t\rightarrow s\) 的最大流 \(f_{t\rightarrow s}\) 。答案就是 \(|f_0|_{s\rightarrow t}+|f_{s\rightarrow t}|-|f_{t\rightarrow s}|\)

混合图欧拉回路

咕咕咕

最小割

最大带权闭合子图

这个问题基于一个有向图 \(G=(V,E)\) ,对于所有的 \(u\in V\) ,都有一个实数的权值 \(w_u\)

它的一个闭合子图(实际上是一个子集)被定义为 \(V'\) ,满足:

  • \(V'\subseteq V\)
  • 对于任意的 \(u\in V',v\in V\) ,如果在 \(G\) 上, \(u\) 可以到达 \(v\) ,那么 \(v\in V'\)

并定义一个闭合子图的权为 \(\sum_{u\in V'}w_u\)


我们将其转化为最小割问题:

首先我们找出每个点的两种情况:属于 \(V'\) 或者不属于 \(V'\) ,其中前者对应在割中属于 \(S\) ,后者对应在割中属于 \(T\)

注意到我们的最小割计算的是代价,所以对于 \(u(w_u\ge0)\) ,它属于 \(T\) 就会带来 \(w_u\) 的代价,因此需要连接 \(s\rightarrow u\) ,容量为 \(w_u\);而对于 \(u(w_u<0)\) ,它属于 \(S\) 就会带来 \(-w_u\) 的代价,因此需要连接 \(t\rightarrow u\) ,容量为 \(w_u\)

考虑 \(E\) 中的边的限制。对于 \((u,v)\in E\) ,如果 \(u\in S\)\(v\in T\) ,这就是不合法的情况——即,我们需要在这种情况发生时,让 \(s\)\(t\) 连通,于是不难想到连接 \(u\rightarrow v\) ,容量为 \(+\infty\)

答案就是:

\[\sum_{u\in V}w_u[w_u\ge0]-\min_{[S,T]}\{c(S,T)\} \]


设构建的网络为 \(G_n=(V_n,E_n)\)

简单证明一下:

  1. 定义简单割为不包含 \(+\infty\) 的割边的割。

    那么网络上的最小割一定是简单割。

    证明

    \(s\) 的所有出边割掉,我们已经得到了一个割 \([\{s\},V_n-\{s\}]\) ,而其中并不包含 \(+\infty\) 的割边,且必然比包含 \(+\infty\) 的割边的割的容量小。

    又因为最小割是容量最小的割,那么它的容量一定小于构造的割,所以最小割一定是简单割。

  2. 网络上的一个简单割与原图上的一个闭合子图一一对应。

    证明

    • 证明:简单割 \(\rightarrow\) 闭合子图

      找出一组简单割 \([S,T]\) ,此时我们让 \(V'=S-\{s\}\) ,显然满足 \(V'\subseteq V\) 的条件。

      反证,假设有 \(u\in V',v\in V-V'\) ,而在 \(G\)\(u\) 可以到达 \(v\) ,还原到 \(G_n\) 上,必然有 \(u\in S\)\(v\in T\)

      由于简单割的割边一定不包含 \(+\infty\) 的割边,因此 \(u\rightarrow v\) 的路径上的边一定没有被割,因此 \(u\)\(v\) 应该属于同一个集合,矛盾。

      因此简单割一定对应了一个闭合子图。

    • 证明:闭合子图 \(\rightarrow\) 简单割

      对于闭合子图 \(V'\) ,我们构造割 \([S=V'\cup \{s\},T=V\setminus V'\cup\{t\}]\)

      考虑割是否包含 \(+\infty\) 的割边。假设有,不妨设边为 \(u\rightarrow v\) ,那么 \(u\in S\)\(v\in T\) 。由于边权为 \(+\infty\) ,所以 \((u,v)\in E\) ,这与 \(V'\) 是闭合子图矛盾,所以 \([S,T]\) 是简单割。

      因此一个闭合子图一定对应了一个简单割。

    这一结论为下面的内容奠定了基础。

  3. " 答案 " 就是最大权闭合子图的权值和。

    证明

    对于任何一个简单割 \([S,T]\) 有:

    \[\begin{aligned} &\sum_{u\in V}w_u[w_u\ge0]-c(S,T)\\ =&\sum_{u\in V}w_u[w_u\ge0]-\left(\sum_{u\in S-\{s\}}(-w_u)[w_u<0]+\sum_{u\in T-\{t\}}w_u[w_u\ge0]\right)\\ =&\sum_{u\in S-\{s\}}w_u \end{aligned} \]

    而根据我们的证明方式, \(S-\{s\}\) 就是一个闭合子图。因而一个割的容量与一个闭合子图的权是对应的。

    注意到上式中 \(\sum_{u\in V}w_u[w_u\ge 0]\) 是定值,由于我们证明了割集合闭合子图集是等价的,因此最小化 \(c(S,T)\) 即可最大化权。

最大带权子图

对于一个无向图 \(G=(V,E)\) ,每个点有一个正实数权 \(w\) ,每条边有一个正实数权 \(W\)

定义一个子图 \(G'=(V',E')\) ,满足 \(V'\subseteq V,E'\subseteq E\) ,且 \(\forall (u,v)\in E',u\in V',v\in V'\)

定义它的权为 \(\sum_{e\in E'}W_{e}-\sum_{u\in V'}w_u\)

求无向图中的最大权的子图。


比较显然的做法是:对于每条边建立点,对每个点再建立点。如果一条边 \((u,v)\) 被选择,就说明 \(u,v\) 都必须被选择,转化成最大权闭合子图问题。

上面这种做法不够有些,点总共有 \(n+m+2\) 个。注意到由于 \(W>0\) ,所以当 \(V'\) 确定的时候,我们必然尽量多选边,因此 \(G'\) 一定是 \(V'\) 生成的诱导子图。此时有 \(E'=E\cap (V'\times V')\)

直接找出 \(E'\) 不太方便,我们考虑减去不在 \(E'\) 中的边;那么此时的边权就是:

\[\sum_{u\in V'}\sum_{(u,v)\in E}W_{(u,v)}-\sum_{u\in V'}\sum_{v\in V-V'}W_{(u,v)}[(u,v)\in E] \]

\(d_u=\sum_{(u,v)\in E}W_{(u,v)}\) ,则有:

\[\begin{aligned} &\frac 1 2\left(\sum_{u\in V'}d_u-\sum_{u\in V'}\sum_{v\in V-V'}W_{(u,v)}[(u,v)\in E]\right)-\sum_{u\in V'}w_u\\ =&\frac 1 2\left(\sum_{u\in V'}(d_u-2w_u)-c(V',V-V')\right) \end{aligned} \]

后半部分可以类比网络流中的 " 割的容量 " 。不难想到使用最小割:

  • 对于 \(u\) ,我们认为 \(u\in S\) 表示 \(u\) 被选中, \(u\in T\) 表示 \(u\) 没被选中;
  • 选择 \(u\) 会带来 \(d_u-2w_u\) 的代价,这个连接见仁见智。
  • 如果 \((u,v)\in E\) ,并且 \(u\in S,v\in T\) ,我们需要计算它的代价。因此连接 \(u\leftrightarrow v\) ,容量为 \(W_{(u,v)}\)

费用流

如果需要进行转化,为了避免歧义,我们认为原图为 \(G=(V,E)\) ,源汇分别为 \(s,t\) ;新图为 \(G_s=(V_s,E_s)\) ,源汇分别为 \(s_s,t_s\)

上下界费用流

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

类比普通无源汇上下界可行流,我们可以直接在边上加上费用,然后让源点和汇点连的边的费用为 0 即可。

注意初始时我们让每条边达到下界的时候需要计算达到下界需要的费用。

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

类比普通有源汇上下界可行流,在上一部分的基础上连接 \(t\rightarrow s\) ,容量为 \(+\infty\) 且费用为 0 即可。

有源汇上下界最小费用最大流

类比普通balabala,求出可行流之后再跑一组 \(s\rightarrow t\) 的最小费用最大流即可。

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

瞎吹出来的

类比普通balabala,求出可行流之后,拆掉 \(t\rightarrow s\) 的边,跑一组 \(t\rightarrow s\) 的最小费用最大流。此时 \(t\rightarrow s\) 经过的会有残余网络中的边,因此费用恰好会抵消。

有负圈(负权边)的最小费用最大流

此时直接套用 SSP 算法是解不出来的,最短路算法会直接掉到负环里面去。

考虑贪心地构造一组初始解——选中所有负权边让它们满流。现在我们需要干两件事:

  1. 通过调整边的流量得到一组可行流
  2. 在可行流的基础上继续流得到最小费用最大流

处理第一步:类比有源汇上下界最小费用可行流,现在我们可以计算 \(I_u\) 为进入 \(u\) 的负权边的容量之和, \(O_u\) 为从 \(u\) 出发的负权边的容量之和。接着对于 \(I_u\not= O_u\) 的边就可以类比连接 \(s_s\)\(t_s\) 的边;记得同时也要连接 \(t\rightarrow s\) 的边。

唯一的区别是,这里我们可以给负权边退流,因此对于容量为 \(c\) ,费用为 \(w\) 的负权边 \(u\rightarrow v\),我们需要在新图中建立 \(v\rightarrow u\) ,容量为 \(c\) ,费用为 \(-w\) ,表示退流这一选择。

跑出可行流之后再跑一组 \(s\rightarrow t\) 的最小费用最大流即可。

posted @ 2020-12-26 14:42  crashed  阅读(108)  评论(0编辑  收藏  举报