网络流最大流问题
我们围绕一道题来讲解吧
蓝桥杯-算法训练-网络流裸题
首先,何为网络流最大流问题?
所谓网络或容量网络指的是一个连通的赋权有向图 D= (V、E、C) , 其中V是该图的顶点集,E是有向边(即弧)集,C是弧上的容量,即设每条路线(u,v)都有一个非负容量c(u,v)。此外顶点集中包括一个起点和一个终点。网络上的流就是由起点流向终点的可行流,问怎样安排使得总流量最大。这样的问题被称为网络流最大流问题。 -----百度百科
可行流:
对于每条路线(u,v)上给定一个实数f(u,v),满足 0≤f(u,v)≤c(u,v),则称f(u,v)为路线(u,v)的流量。而对于一组具有源点和汇点,且 总流出量=总流入量,则称为网络中的一条可行流。
拿例子来说 画的有点丑 一个可行流:5。
最大流:
联系上下文可知,就知道它是可行流中最大的一个流。
*所以最大流的情况可能不止一种。
其次,怎么求最大流呢?
Ford-Fulkerson(福特-福克森)算法:
Ⅰ.如果存在增广路径,就找出一条增广路径。
Ⅱ.然后眼该条增广路径进行更新流量。
每次操作时从源点搜索出一条到汇点的路径(可行流),然后将该路径上所有的容量减去该路径上容量的最小值,然后对路径上每一条边<u,v>添加或扩大反方向的容量,大小就是刚才减去的容量。一直到没有路为止。此时辅助图上的正向流就是最大流。 -------百度百科
这个算法的一个关键部分就是如何找出增广路径:
Ⅰ. 找到一条从源点到汇点的路径,若(u,v)的方向与路径一致,这称为 正向边 ;相反则称为 逆向边 。
Ⅱ.该路径上的每条边满足,流量非负,且未达到流量上限,即未达到容量上限。(要分清流量和容量的区别)
*增广路径的查找可以运用bfs或dfs的方法;
再者,现在有了增广路径了,如何增广呢?
设ins为每次最后计算出的增加流量,先使ins=INF(正无穷)
Ⅰ.计算ins
若(u,v)为正向边,则ins=min(ins,c(u,v)-f(u,v));
若(u,v)为逆向边,则ins=min(ins,f(u,v));
Ⅱ.更新流量
若为正向边,f(u,v)+=ins;
若为逆向边,f(u,v)-=ins;
完整过程(我偷了个图过来,我懒得画 样例的过程太多了):
图片来源https://blog.csdn.net/mystery_guest/article/details/51910913
这是样例最后运行完的图(希望你们能get到我的意思吧):
最后献上AC代码:
<