参考大佬的博客:https://blog.csdn.net/clove_unique/article/details/54884437
1.无源汇的可行流
可行流算法的核心是将一个不满足流量守恒的初始流调整成满足流量守恒的流。
建图方法:
- 附加源点和附加汇点
- 如果有边(u,v),存在上下界L,R,那么,在这条边上建一个容量为R-L的边
- 为了保证可行,使每个点的流出量等于流入量,需要附加一些边:(1)如果某个点在当前图的流入量比流出量多x,那么这个点在附加流中的流出量比流入量多x;(2)如果某个点在当前图的流入量比流出量少x,那么这个点在附加流中的流出量比流入量少x. 记d(i)为流入这个点的所有边的下界和减去流出这个点的所有边的下界和 :若d(i)>0,那么连边ss->i,流量为d(i);若d(i)<0,那么连边i->tt,流量为-d(i)
b(u,i)为从u到i的下界,f为实际流
求解:
在新图上跑ss到tt的最大流 。如果附加边满流就说明可行,如何说明是附加边满流:即如果最大流的大小等于ss出发的所有边的流量上限之和(此时指向tt的边也一定满流,因为这两部分边的流量上限之和相等)。
那么原图中每一条边的流量应为新图中对应的边的流量+这条边的流量下界
2.有源汇的可行流
建图方法:
将有源汇的可行流转变成无源汇的可行流
首先添加一条从t回到s的边,上界是inf,下界是0,转变成无源汇的可行流
其余同上
求解:
同上
3.有源汇的最大流
建图方法:
首先套用上面的建图,求出一个有源汇有上下界可行流.此时的流不一定最大。
求解:
先跑超级源点到超级汇点的最大流,如果此时附加边满流,说明存在可行流。
将t到s的这条边拆掉,跑s到t的最大流。最终的最大流流量=可行流流量(即t到s的无穷边上跑出的流量)+新增广出的s-t流量。
或者不拆这条边,直接跑s到t最大流,最大流的结果即是所求结果。