参考:
[1] : https://blog.csdn.net/corsica6/article/details/81488993
[2] : https://www.luogu.com.cn/problemnew/solution/P4553
说明
- 可行流:一个网络网络中,存在一条流,满足任意点的总流入量等于总流出量(即流量守恒)。
- 边的流量:网络流连边时连的反向边上的flowflowflow值,即为该边流量。(考虑在流过这条边时,在正向边上减去了流量大小的值,而反向边上恰好加上了这个值)。
无源汇上下界可行流
给定 (n) 个点, (m) 条边的网络,求一个可行解,使得边 ((u,v)) 的流量介于 ([B(u,v),C(u,v)]) 之间,并且整个网络满足流量守恒。
设:(inB[u] = sum B(i,u), outB[u] = sum B(u,i), d[u] = inB[u] - outB[u])
新建源汇,S' 向 d>0 的点连边,d<0 的点向 T‘ 连边,容量为相应的d。
在该网络上求最大流,则每条边的流量+下界就是原网络的一个可行流。
有源汇上下界可行流
从T到S连一条下界为0,上届为 +inf 的边,在原网络中,从S到T的流量全部流回去,流量守恒,然后转换成了无源汇的网络,然后求解无源汇上下界可行流即可。
最终T->S 这条边的流量为原图总流量
有源汇上下界最大流
求出可行流之后,再求原残余网络的最大流,之前的可行流再加上残余网络最大流就是原来的最大流
有源汇上下界最小流
求出可行流,然后T->S的边的流量即为可行流大小,再原图残余网络中从T->S 跑最大流,用可行流减去残余网络最大流,就是最小流。
注:原图不包括T->S 的边以及S'和T'所连接的所有边
例题
BZOJ-3698. XWW的难题
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int inf = 0x3f3f3f3f;
#define dbg(x...) do { cout << "