zoukankan      html  css  js  c++  java
  • 网络流模型基础

    最大流

    上下界网络流

    对于该问题的图 (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 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) 上有:

    [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)

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

    而对于 (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),即它满足你在网上可以看到的其它版本的构造方法:

    1. 如果 ((u,v)in E) ,连接 (u ightarrow v) ,容量为 (c_u(u,v)-c_l(u,v))
    2. 如果 (I_u>O_u) ,连接 (s_s ightarrow u) ,容量为 (I_u-O_u)
    3. 如果 (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)

    答案就是:

    [sum_{uin V}w_u[w_uge0]-min_{[S,T]}{c(S,T)} ]


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

    简单证明一下:

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

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

      证明

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

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

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

      证明

      • 证明:简单割 ( 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]) 是简单割。

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

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

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

      证明

      对于任何一个简单割 ([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') 中的边;那么此时的边权就是:

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

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

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

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

    • 对于 (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)})
  • 相关阅读:
    禅道使用-升级
    Maven 的这 7 个问题你思考过没有?
    https及证书
    Linux下查看/管理当前登录用户及用户操作历史记录
    禅道的安装
    Linux添加/删除用户和用户组
    Spring注解@Component、@Repository、@Service、@Controller区别 .
    myeclipse,eclipse打开当前文件所在文件夹
    java开发常用工具
    Django环境搭建之安装mod_wsgi模块
  • 原文地址:https://www.cnblogs.com/crashed/p/14192828.html
Copyright © 2011-2022 走看看