网络流算法详解
网络流算法在许多实际问题中有应用,如匹配问题,著名的Hall婚姻定理。这里不证明“最大流最小割定理”,简单解释求最大流的Ford-Fulkerson算法。接下来分别详述时间复杂度为O(VE2)的Edmonds-Karp算法和时间复杂度为O(V2E)的Dinic算法。至于较新的预留推进算法就不介绍了,这个算法证明比较难,感兴趣的可以看看算法导论。
本文所用到的网络流如图1,s为原点,t为汇点,边上的值表示边的容量c(u,v),如c(s,v1)=15,c(v1,v2)=8。流用符号f(u,v)表示,如图2,流的容量f(s,v1)=10,f(v1,v2)=5。剩余容量cf(u,v)=c(u,v)-f(u,v)。在原剩余网络中找到一条流后,修改原网络边的剩余容量得到剩余网络Gf,如图3所示。注意剩余网络中有一些新添加的边即反向边的容量,为流的反馈。在图3中,有f(v1,v3)=5,那么有f(v3,v1)=-f(v1,v3)=-5,然后cf(v3,v1)=c(v3,v1)-f(v3,v1)=0-(-5)=5。
图1 网络流的一个例子
1.Ford-Fulkerson算法
算法的主要思想:
1)初始化一条容量为0的流f和一个剩余网络Gf,第一个剩余网络为原图G,每条边的剩余容量初始化为每条边的初始容量cf(u,v)=c(u,v)。
2)在剩余网络Gf中寻找增广路径p,取增广路径p中的边的剩余容量cf(u,v)最小值作为流的增量△f,使得f’=f+△f。修改剩余图中每条边的容量cf’(u,v)=cf(u,v)- △f得到剩余网络Gf。(补充说明:原算法中的△f可以为单位1)
3)重复步骤2),直到找不到一条增广路径为止。
寻找一条增广路径的方法如图4所示,然后确定增广路径上的流增量△f。本例中△f=3。
整个网络可以用邻接表或矩阵表示,网络的边即为矩阵中的元素,网络的节点则为矩阵一维的下标。这里网络中每条边最好用一个结构体表示。结构体包含边的容量和每次通过的流量这两个变量。
下面是一个例子: