说在前面
天天熬夜,me都要累死了=A=
吃个橙子清醒一下…
无源汇可行流
抽象出来是这样的:一个没有源点和汇点的有向图(环流),边有流量上下界限制,需要求出一个可行流
建图方法
记点u的流入流量下界总和为in[u],流出流量下界总和为out[u],新建 补流源点SS 和 补流汇点TT
- 对于原图中的边u->v,限制[a,b],在新图中建u->v,容量b-a
- 对于原图中的每个点u
- 如果入度大于出度,那么建边SS->u,容量in[u]-out[u]
- 如果出度大于入度,那么建边u->TT,容量out[u]-in[u]
运行
在新图上跑从SS到TT的最大流,如果满流,那么原图有解,且其中一种可行解中,每条边的流量为 原流量下界+新图流量
如果不满流则无解。
正确性
这个问题的难点在于处理流量下界,用到的核心思想是流量守恒
先假设所有的边已经有下界的流量,当然,这样的图可能不满足流量守恒,于是考虑如何使之回复平衡
只考虑点u的情况下,如果in[u]和out[u]相等,那么已经是平衡的,可以不用管
而in[u]和out[u]不相等时,可以用较小的那个「抵消」掉较大的那个的一部分,剩下的就是待平衡的流量。
比如,如果是in[u]>out[u],说明流入量大于了流出量,那么在用较大的流入 填满了 较小的流出下界之后,流入还多了一部分。那么就需要存在一种流动方法,使得这一部分流出并使原图流量平衡,于是新建一条边SS->u,容量in[u]-out[u]。in[u] < out[u]的情况同理。那么在新图上跑最大流,如果能跑满流,说明原图存在方案满足流量守恒,于是有解。
关于更理性的证明,可以参考zyf2000的博客
有源汇可行流
抽象出来是这样的:一个有源点和汇点的有向图,边有流量上下界限制,需要求出一个可行流
建图方法
考虑和无源汇有什么不同。有源汇的图中,除了源点和汇点,其他所有点都满足流量守恒。那么不妨将之改造成一个环流,即连边T->S,容量inf。再在此图基础上按照 无源汇可行流 建边即可
运行
和无源汇可行流一样的qwq
有源汇最大流
抽象出来是这样的:一个有源点和汇点的有向图,边有流量上下界限制,需要求出一个最大流
建图方法
和有源汇可行流一样
运行
这要求出一个最大流,首先得有解才行。因此先运行一遍从SS到TT的最大流,如果满流,说明有解,也存在最大流
然后直接在之前的残余网络上跑一边S到T的最大流,即是答案
正确性
第一次运行SS到TT的最大流,是为了保证有解,同时这个跑出来的也是原图的一个可行流。
这时,因为原图中所有的边容量已经减去下界,所以这个下界是不可反悔的。并且T->S边的流量其实就是第一遍跑完之后S留到T的流量(比如u->v这样的边,在第一次网络流中通过SS->v->T->S->u->TT的方式贡献了流量)。那么现在直接在原图上跑S到T的最大流,不仅能得到原来图上的流量(反悔了T->S),还能在原来的可行流上增广,于是这样就得到保证下界的最大流。
有源汇最小流
抽象出来是这样的:一个有源点和汇点的有向图,边有流量下界限制,需要求出一个最小流。(最小留图一般是没有上界限制的,除非要判不可行)
建图方法
和有源汇可行流一样
运行
先不加T->S这条边,跑SS->TT的最大流
然后再加上T->S这条边,跑SS->TT的最大流,此时新增的流量(即T->S的流量)即答案
正确性
因为没有上界,因此一定存在可行流,那么眼下的问题就是如何找最小流
注意到,之前在新图跑有源汇可行流时,并没有在意流量是怎么流的,只要能满流就可以了,而这无疑会带来多余的流量,比如下图:
这张图中,1->2和3->4都有1的下界。其中一个可行流是从SS出发到2和4分别1的流量,绕过T->S之后再流向TT,那么此时原图流量为2。但是我们发现,其实SS->2的这个流量完全没必要经过T->S补流,直接SS->2->3->TT就完了,这样的话,原图流量就为1,并且也是可行流。
于是这启发我们,先不加T->S这一条边,然后在图上跑一遍最大流,让所有的流量尽可能不绕过T->S(绕过T->S就相当于是加了流量来辅助平衡流量,即SS->v->T->S->u->TT这样的路径),而是让这些不平衡的流量先自我平衡一遍。然后加上T->S再跑一遍最大流,此时经过T->S的就是必须的流量了,也就是最小流。
有源汇可行最小费用流
抽象出来是这样的:一个有源点和汇点的有向图,边有流量上下界限制,需要求出一个费用最小的可行流。
建图
大体和有源汇可行流一样
原来的边费用不变,补流的边费用为0
运行
首先满流才有可行流解
在新图里跑最小费用流,答案就是原来每条边的 下界限制*费用 之和+跑出来的费用
正确性
其实是差不多的,首先下界的流量费用是必须的,然后就是考虑让流量平衡
在平衡过程中优先选择较小费用的边进行平衡,也就是普通费用流的想法,于是直接在新图跑费用流即可。