最近在看网络流,看了算法导论不是很懂。。不知道书里那个图是不是错了,搞得我有点混乱;
然后就从网上查下资料,翻了几个大神的博客,就搞懂了个大概是怎么回事;网络流里有很多
算法,因为是入门,所以就写了个EK(Edmonds-Karp)求最大流的算法,顺便做了个模板题;
写的时候还行,大概思路没什么问题,就是实现的时候有点小错误,下面是本人学习中的一些理解:
Edmonds-Karp求最大流的算法核心思想就是不断找增广路,每找到一条增广路,记录增广路中
边流量最少的值d,然后让当前找到增广路中的每一条正向弧减去d,让反向弧加上d,当不再找
到增广路的时候,就证明当前的总流量已经是最大流;至于怎样找增广路。。一致认为BFS是最好
的方法了。。。
增广路(摘自NOCOW):设f 是一个可行流,W是发点到收点的一条有向道,如果W满足下列条件,称之为关于可行流f的一条可增广道
(又称可扩道):
1. 每条正向弧是非饱和弧,
2. 每条反向弧是非零流弧.
做完题之后,发现如果不加反向弧好像也可以算出答案,但是交上去又WA,然后百度搜了下
为什么要有反向边或者残余图?
前面我们确定了一条路径的最小流量之后,我们实际上可以把这部分流量从图中删去(这个可以看做减治的过程):因为这个路径以后是不会更改的,而且路径之间互不影响。但是也会出现一定的问题:结果往往不是最优的。反向边和残余图可以解决这一问题。
最近又看了算法导论之后,看到了个可以作为不加反向弧而得不到最优解的反例,如下图
第一张图是最原始的图,值为边的容量,第二张图是找出s->v1->v2->t增广路后不加反向弧的残余图;明显的,如果不加反向弧,v1->v2一旦成为饱和弧后,就不能恢复,而这样最后算出来的流值是199,但是正确的最大流值是200,所以不加反向弧不能保证得到的是最优解(这算是证明么- -!);