上下界网络流

上下界网络流

0x00 前言

  • 这又是一个大坑,有必要填上,学会了可以暴力建图,省去一些繁琐的构思

0x01 什么是上下界网络流

  • 这里我们把网络流分为几种情况:有无源汇,只要求可行或最大或最小,有无费用,是否有下界
  • 有源汇网络流:除了一个S(源)流出量没有限制和一个T(汇)流入量没有限制,其他节点必须满足流量守恒
  • 无源汇网络流:所有点都必须满足流量守恒
  • 可行流:是否存在一种流量的方案似的网络流满足流量守恒的条件
  • 最大流:满足流量守恒条件下最大的流量,最小流类似
  • 费用流:满足一定条件(最大流,最小流)下费用最大或最小
  • 普通的网络流有一个上界,即每条边最多流量是给定的。上下界网络流同时给出了下界,即一些边的流量要求至少为一个值
  • 显然可行流总是得和上下界放在一起,不然一个流量为0的方案总是可行的
  • 上下界网络流一般用于求解各种有上下界网络流问题(废话)

0x02 做一些定义

  • N:整个网络
  • p:一个节点
  • e:一条边
  • S:源
  • T:汇
  • low_in[p],low_out[p]:p的下界流入和流出量(所有入边流量的下界和,所有出边流量的下界和)
  • free_in[p],free_out[p]:p除了下界流量之外的流入和流出量
  • lower[e],upper[e]:e的下界和上界
  • SS:超级源
  • TT:超级汇

0x03 从最简单的开始——无源汇可行流

  • 假设这个网络叫N
  • 上界的问题我们是身经百战,见得多了,但是下界没怎么碰到过
  • 但是为什么从无源汇开始呢?不是有源汇的问题我们更熟悉么?
  • 你要是问我能不能在有下界的图里直接增广,那我明确地告诉你:你们这样是不行的。
  • 不管是dinic,最高标什么乱七八糟的网络流算法都无法求解有下界的网络流
  • 我们只能考虑对图做一些变换,把下界去掉
  • 显然的一种想法是先给条边强制流上lower[e]的流量,剩下upper[e]-lower[e]的流量是自由的,即让每条边的流量变为new_lower[e]=0,new_upper[e]=upper[e]-lower[e],我们把这个改过的网络叫做N'
  • 想法很显然,正确性也很显然,是错的
  • 为什么呢?因为这么一搞不能保证流量守恒了。
  • 我们考虑这点p流量守恒的表达式
  • low_in[p]+free_in[p]=low_out[p]+free_out[p]
  • 事实上我们把low_in,low_out这部分删去了,这会导致流量不平衡
  • 这并不难解决,我们新建SS和TT,对于每一条边<u,v>,下界为lower,我们拆成从SS向v连容量为lower的边,从u向TT连容量为lower的边
  • 这易于理解,我们相当于把lower这一部分拆了出去
  • 然后对N作上文所提到的变形
  • 这里有一个简单的小优化,重新考虑p流量守恒的表达式
  • low_in[p]+free_in[p]=low_out[p]+free_out[p]
  • 稍作变形
  • low_in[p]-low_out[p]=free_out[p]-free_in[p]
  • 如果令 dlt=low_in[p]-low_out[p]
  • 发现如果在N'中求出了一个可行流,p这个点在N中实际的流出比流入要多了dlt(假设dlt为正,负一会考虑)
  • 从SS向p连一条流量为dlt的边。
  • 如果dlt为负呢?说明这个点流入比流出多了,从这个点向TT连一条流量为-dlt的边
  • 这相当于把原来的一些SS-p-TT的边合并了,减少了边的总数,容易得到这两个图的性质是等价的。
  • 变形完后,从SS向TT做一次有源汇最大流,如果SS所有的流出边都满流,那么可行流就存在
  • 为什么?
  • 首先容易发现如果SS流出的边都满流了,那么流入TT的边肯定也都满流了(这两部分总流量是一样的,原因可以考虑N中一条边的下界对N'的影响)
  • 考虑我们建图的过程,如果SS所有的流出边都满流了,那么说明:
  1. 下界都被满足了
  2. 所有点都满足流量守恒
  • 好了呀,你还要怎么样嘛,这不就是我们要求的东西么
  • 最后每条边的实际流量就是它的反向边流量加上 下界流量

0x04 无源汇最大/最小流

  • 给每条边加一个1的费用
  • 用下面提到的无源汇上下界费用流做

0x05 有源汇最大流

  • 这妙极了,看到这的读者不妨先自行思考一番,我们能否套用刚才求解无源汇可行流的方法?
  • 我们给T->S加一条容量为[0,INF]的边E!
  • 这样就变回了一个求解可行流问题,做一遍可行流
  • 此时E的流量就是S->T的当前流量C1(考虑一下为什么),但是C1不一定是最大流,简单想个例子就可以得出这个结论
  • 我们把E删去,再在N'的残量网络中做一次从S到T的增广(不是SS到TT!),设增广的流量为C2,总的最大流就是C1+C2,由于在残量网络中增广不改变流量守恒性质,这个算法的正确性是显然的

0x06 有源汇……最小流?

  • 有了下界就有了求最小流的坑爹问题
  • 有个显然的想法,先加T->S的INF边求可行流C1,然后C1是不是最小流呢?
  • 并不是,这里请读者自行举例以加深对此的理解,给个提示:考虑图中的成环流量
  • 然而我们可以在残量网络中退流
  • 把INF边删了,从T向S跑一遍最大流,流量为C2,C1-C2即为最小流
  • 正确性和上面一样啦

0x07 无源汇费用流!

  • 老样子,先求一个可行流?
  • 这里构图的时候遇到了点麻烦,边有费用,而且费用不一样,如果用优化版的构图方法无法合并一个点的出边和入边
  • 只好每条边都拆成单独的两条边了
  • 每条边的费用呢?费用会被算两次耶?选一条边加费用咯,任性,我喜欢选SS到v的边
  • 然后直接从SS到TT跑费用流即可。
  • 事实上我还YY了一个愚蠢的方法,有兴趣的读者可以尝试一下
  • 先在图中求一个可行流,然后运用消圈算法优化答案
  • 消圈算法:用spfa在图中找负/正环
  • 推荐做一下bzoj3876支线剧情,codevs上的支线剧情真坑爹,时限只有2s,相比之下bzoj有10s
许愿弥生改二
原文地址:https://www.cnblogs.com/LoveYayoi/p/6745524.html