不得不说网络流算法是很让人无语的算法,要想高效率竟然要非递归实现深搜,很无奈,到现在还是在低效率中挣扎!
最大流算法的证明就不说了,无非就是最大流最小割定理的推导,定理描述如下:
对于任意给定的网络D=(V,A,C),从出发点vs到收点vt的最大流的流量必等于分割的最小截集的容量!
至于截集,定义为:
给定网络D=(V,A,C),若点集V被分割成两个非空集合V1和V2,使得V=V1+V2,V1∩
V2=φ(空集),且vs∈V1,vt∈V2,则把始点在V1,终点在V2的弧的集合称为分离vs和vt的
一个截集
然后,网络流算法最重要的增广链,正式定义为:
设 f = {Fij}是网络D=(V,A,C)上的一个可行流,u 是从 Vs到 Vt的一条链,若u 满足下列条件:
(1)在弧 (vi,vj)∈μ+上,即 u+中的每一条弧都是非饱和弧;
(2)在弧 (vi,vj)∈μ-上,即u- 中的每一条弧都是非零流弧。
则称 是关于 的一条增广链。
找最大流就是不断的找增广链,直到找不到增广链为止!
朴素的有Ford —— Fulkerson标号法,就是每次从源点开始找增广链,然后更新网络,再找增广链,再更新。。。
伪代码可以表示为:
void Ford_Fulkerson()
{
int max_l = 0;
while (存在增广链)
{
max_l += 可更新流量;
更新残余网络;
}
}
另外网络流算法多种多样,比如dinic,有兴趣可以学习学习!
代码如下:
#include <iostream>
#include <cstring>
#include <cstdlib>
using namespace std;
const int Max = 225;
const int oo = 210000000;
int n,m,c[Max][Max],r[Max][Max],source,sink,nc,np;
int dis[Max],block[Max];
void initialize()// BFS建立层次图,
{