zoukankan      html  css  js  c++  java
  • 学习上下界网络流小记

    前言

    这个上下界网络流是一个以前我这个巨弱弱想都不敢想的一个东西。
    然而,最近一次比赛居然考了这个东东。
    于是整个机房掀起了破烂学上下界网络流的热。
    那么我也来学学。

    预备知识

    要懂得很多很多的网络流知识比如最大流这种基础的。
    当然,还有一个流量的平衡条件:
    f(u,x)=f(x,v)sum f(u,x)=sum f(x,v)
    这个条件可以用来判断可行性。为什么呢?
    这里有一条定义,自己看吧(其实画个图更容易理解)
    ——————————————————————————
    在图中有一条从 s 到 t 的路径, 这条路径上起点 fo−fi=f, 终点 fi−fo=f, 其他的点 fi==fo, 并且所有的边的当前流量小于等于最大流量.(其中 fi 代表流入流量, fo 代表流出流量)
    ——————————————————————————

    正题

    实际上,这个上下界网络流是有很多种类型的,我一一来阐述。

    无源汇上下界可行流

    设,上界为up,下界为down
    建图方法
    我们可以考虑建一个新图。
    首先弄一个新的源点和汇点ns和nt。
    然后,对于原图中每条(u,v)的边,建u→v流量为up-down
    然后,我们设一个d(x)表示x流入x点的边的下界和,减去流出x点的边的下界和。
    当,d(x)>0则连ns→x流量为d(x)的边。
    否则,d(x)<0则连x→nt流量为-d(x)的边。
    我们不妨称后面这两条边为附加边。

    流程
    从源点流到汇点,当每条附加边已经流满的时候,则可以确定这个图可行。

    证明
    我们设一个g(u,v)表示实际流量f(u,v)=up(u,v)+g(u,v)
    那么0<=g(u,v)<=up(u,v)-down(u,v)
    如果我们不加附加边,这显然是错的。
    那么我们看看附加边的作用:
    f(u,x)=f(x,v)因为要满足平衡条件sum f(u,x)=sum f(x,v)
    down(u,x)+g(u,x)=down(x,v)+g(x,v)那么sum down(u,x)+g(u,x)=sum down(x,v)+g(x,v)
    down(u,x)down(x,v)=g(x,v)g(u,x)sum down(u,x)-sum down(x,v)=sum g(x,v)-sum g(u,x)
    d(x)=down(u,x)down(x,v)因为d(x)=sum down(u,x)-sum down(x,v)
    d(x)=g(x,v)g(u,x)d(x)=sum g(x,v)-sum g(u,x)
    当,d(x)>0时,那么d(x)+g(u,x)=g(x,v)d(x)+sum g(u,x)=sum g(x,v)
    当,d(x)<0是,那么d(x)+g(u,x)=g(x,v)-d(x)+sum g(u,x)=sum g(x,v)
    图长这样——
    在这里插入图片描述
    这样就可以保持新图的平衡条件。

    有源汇上下界可行流

    建图方法
    由于原图中,只有源点与汇点不满足平衡条件,于是强行在汇点连条无线大流量个边到源点即可。
    其余同上。
    流程
    同上。
    证明
    同上。

    有源汇上下界最小流

    建图方法
    同“无源汇上下界可行流”
    流程
    先在这个图上判断可行性。
    此时,答案即为超级源到超级汇的最大流。
    证明
    由于补流与分流是流每条边的下界的,一旦达到下界后,就代表可行。
    此时,下界的答案即为补流与分流的流量。
    但是光到达下界不行,还有可以到达上界到下界之间的答案。
    于是乎,我们就把原来每条边的最大流加入答案即可。

    有源汇上下界最大流

    建图方法
    同“有源汇上下界可行流”
    流程
    先在这个图上判断可行性。
    此时,超级源到超级汇的补流与分流的流量先加入答案。
    然后,我们把超级源以及超级汇删掉,并且把t→s的边也删掉。
    再做一遍最大流,即可。
    证明
    类似于上面。

    费用流+上下界网络流

    注,这里费用流是最小费用最大流,其他什么流应该是类似的思想。
    建图方法
    首先弄一个新的源点和汇点ns和nt。
    然后,对于原图中每条(u,v,cost)的边,建u→v流量为up-down,费用为cost
    然后,我们设一个d(x)表示x流入x点的边的下界和,减去流出x点的边的下界和。
    当,d(x)>0则连ns→x流量为d(x),费用为0的边。
    否则,d(x)<0则连x→nt流量为-d(x),费用为0的边。
    当然,这个图是有源点与汇点的,那么连汇点到源点流量为无限大,费用为0即可。
    流程
    直接按照费用流的方式跑即可,因为答案统计是和上面一样的。
    别跟我说你不会费用流
    证明
    由于这个图已经奇妙地转化成了普通图,所以不用说了吧。
    运用
    这个费用流只用于满足流量限制后的最小费用,不满足最大流。

    优化

    至此,上下界网络流的一些基本建图方法已经讲完了。
    而且,经过我的一些观察,找到了两种建图方法——
    一种是我上述的方法,在点少边多的图药效奇佳,而且好理性证明。
    另一种是网上学到,在点多边少的图药效奇佳,但是我不会理性证明,只会很感性地理解。(画图)
    在此口胡一下在“无源汇上下界可行流”的建图方法

    • 建立超级源与超级汇。
    • 对于一条边(u,v),建从v→u流量为up-down的边。(注意是v→u)
    • 然后建ns→v流量为down的边。
    • 然后建u→nt流量为down的边。
    • 之后直接求即可。

    这个可以感性理解。
    我们看到原来的u→v,由于下界是down,那么当这条边流过了down之后,相当于u失去down的水,v得到down的水,剩下的是up-down的水。
    这样建图就可以模拟上述过程。

    当然,也可以在最大流那优化。
    如果你会sap、dinic之类的优秀算法,是可以优化很多。
    如果你会把这sap与dinic两算法的优秀之处结合起来,也是可以优化很多。
    对于费用流,可以打zkw使得程序跑得更快。
    当然,如果你打预流推进或高标,时间会降得更多。

    题外话

    至于题目,网上一大堆。
    至于板子,主要就是建图方式。

    参考资料

    https://blog.csdn.net/Clove_unique/article/details/54884437

    我活在这夜里。无论周围多么黑暗,我都要努力发光!我相信着,终有一天,我会在这深邃的夜里,造就一道最美的彩虹。
  • 相关阅读:
    例6-5
    例6-3
    例6-2
    例6-1
    例5-9
    python3
    python3
    python3
    python3
    python3
  • 原文地址:https://www.cnblogs.com/RainbowCrown/p/11148376.html
Copyright © 2011-2022 走看看