先讲最短增广路算法
1、顶点的层次和层次网络
顶点的层次:在残留网络中,把从源点到顶点u的最短路径长度(该长度仅仅是值路径上边的数目,与容量无关),称为顶点u的层次,记为level(u)。源点Vs的层次为0。
将残留网络中所有的顶点的层次标注出来的过程称为分层。
注意:
(1)对残留网路进行分层后,弧可能有3种可能的情况。
· · · · · · 1、从第i层顶点指向第i+1层顶点。
· · · · · · 2、从第i层顶点指向第i层顶点。
· · · · · · 3、从第i层顶点指向第j层顶点(j < i)。
(2)不存在从第i层顶点指向第i+k层顶点的弧(k>=2)。
(3)并非所有的网络都能分层。
层次网络:
对残留网络进行分层后,删去比汇点Vt层次更高的顶点和与汇点Vt同层的顶点(保留Vt),并删去这些顶点相关联的弧,再删去从某层顶点指向同层顶点和低层顶点的弧,所剩余的各条弧的容量与残留网络中的容量相同,这样得到的网络就是残留网络的子网络,称为层次网络,记为G”(V”,E”)。
根据层次网络定义,层次网络中任意的一条弧 < u,v > ,有满足level(u)+1 == level(v),这条弧也叫允许弧。直观的说,层次网络是建立在残留网络基础之上的一张“最短路径图”。从源点开始,在层次网络中沿着边不管怎么走,到达一个终点之后,经过的路径一定是终点在残留网络中的最短路径。
阻塞流:
设容量网络的一个可行流为f,当该网络的层次G”中不存在增广路(即从源点Vs到汇点Vt的路径时),称该可行流f为层次网络G”的阻塞流。
2、最短路增广路径的算法思想
最短增广路的算法思想是:每次在层次网络中找一条含弧数最少的增广路进行增广。最短增广路算法的具体步骤如下:
(1)初始化容量网络和网络流。
(2)构造残留网络和层次网络,若汇点不在层次网络中,则算法结束。
(3)在层次网络中不断用BFS增广,直到层次网络中没有增广路为止;每次增广完毕,在层次网络中要去掉因改进流量而导致饱和的弧。
(4)转步骤(2)。
解释
在最短增广路算法中,第(2)、(3)步被循环执行,将执行(2)、(3)步的一次循环称为一个阶段。在每个阶段中,首先根据残留网络建立层次网络,然后不断用BFS在层次网络中增广,直到出现阻塞流。注意每次增广后,在层次网络中要去掉因改进流量而饱和的弧。该阶段的增广完毕后,进入下一阶段。这样的不断重复,直到汇点不在层次网络中为止。汇点不在层次网络中意味着在残留网络中不存在一条从源点到汇点的路径,即没有增广路。
在程序实现的时候,并不需要真正“构造”层次网络,只需要对每个顶点标记层次,增广的时候,判断边是否满足level(v) = level(u)+1这一约束条件即可。
3、最短增广路算法复杂度分析
最短增广路的复杂度包括建立层次网络和寻找增广路两部分。
在最短增广路中,最多建立n个层次网络,每个层次网络用BFS一次遍历即可得到。一次BFS的复杂度为O(m),所以建层次图的总复杂度为O(n*m)。
每增广一次,层次网络中必定有一条边会被删除。层次网络中最多有m条边,所以认为最多可以增广m次。在最短增广路算法中,用BFS来增广,一次增广的复杂度为O(n+m),其中O(m)为BFS的花费,O(n)为修改流量的花费。所以在每一阶段寻找增广路的复杂度为O(m*(m+n)) = O(m*m)。因此n个阶段寻找增广路的算法总复杂度为O(n*m*m)。
两者之和为O(n*m*m)。
模板在最后
以上介绍最短增广路算法只是为下面介绍Dinic算法而提供给大家一个铺垫,有了以上的基础,接下来我们来介绍Dinic算法,Dinic其实是最短增广路算法的优化版。
·
·
·
·