博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
【算法•日更•第三十四期】最大流算法
阅读量:5288 次
发布时间:2019-06-14

本文共 1115 字,大约阅读时间需要 3 分钟。

▎写在前面

  在之前,我们已经清楚了网络流与最大流是什么,以及增广的操作。

  如果你还不会请点击学习。

  

▎基本思路

  先放上一张图,要不然感觉有点空旷

  

  下方文字请结合上面的图片食用

  先来弄清楚一个概念:容许流,就是从源点到汇点的流,显然,一个图中的容许流不是唯一的,而最大流就是流量最大的容许流。

  我们先假设S是源点,T是汇点,为了寻找S到T的最大流,我们应该不断尝试寻找增流路径,增加容许流的流量,知道无法增加为止。这也被称为增广过程。

▎Ford-Fulkerson标号算法

  还是上面的图。

  我们对于一条边,记录三个值:这条边的容量,已用容量,剩余可用容量(不断增广时会消耗容量)。同时,再增加一个叫做反射弧反向弧的东西,初始全部为0,用于存储一条边(u,v)的逆向边(v,u),虽然不存在,但是可以用于反悔,以便于保证枚举到每一种情况。反向弧虽然名字特殊,但是我们把它视作普通的边。

  这个算法既然叫作标号算法,那么一定是要标号的,对于每个点,都会有两个标号:第一个是前驱(也就是从那里过来的),第二个是当前路径上的最小边权。

  这个算法本质上就是不断搜索,从S标号(无,inf)开始,不断扩展(权值为0的边不选择),到达另一个点,继续标号,如果到达了T,那么最大流加上第二个标号。而前驱的作用则是回溯,把路径上的边全部都减去该路径上的最小边权,同时该边的反向弧也增加最小边权。直到T无法再次被标号,则当前得到的容许流就是最大流。

▎算法图解

  首先放个图:

  

  然后从s开始标号。

  

  然后随便挑一条,走到1号点的位置,然后标号。

  

  接着走到T。

  

  然后发现已经到达了T,T已经被标过号了,于是最大流加1。

  

  然后返回,我们会发现(1,T)这条边减去1之后就是0了,那么为了简洁,我们就可以把它视作没有了,再添一条反向弧。(S,1)也是同理。

  

  接着我们用刚才的方法遍历S -> 2 -> T这条路径。

  

  发现标号了T,那么回溯,并且最大流加4。

  

  

  于是我们就发现无法标号T了,那么此网络的最大流就是1+4=5了。

▎算法的正确性

  虽然无法直接理解这个算法到底为什么正确,但是该有的条件它均已满足:

  ①每条边的长度都不可能是负数。

  ②每次增广时,都能保证每个点流量平衡。

  ③每一次S的出流量和T的入流量都变化相同。

  ④只要最大流是有限的,那么一定会在有限的时间内求出(不会死循环)。

转载于:https://www.cnblogs.com/TFLS-gzr/p/11302819.html

你可能感兴趣的文章
C# Windows Service中执行死循环轮询
查看>>
工具类-格式化小数
查看>>
分库分表-简单总结
查看>>
python deamon(守护)线程的作用
查看>>
Swing实现右下角消息框
查看>>
迭代器和生成器
查看>>
HTML时间监听方法
查看>>
面试题
查看>>
dedecms高级搜索功能(指定模型搜索,一个页面多个搜索)
查看>>
python爬虫(2)--Urllib库的高级用法
查看>>
读取浏览器历史记录操作方法(刷新token)
查看>>
安卓高级6 玩转AppBarLayout,更酷炫的顶部栏 Toolbar
查看>>
两台W7系统的电脑,A电脑可以ping通B电脑,B电脑ping不通A电脑。
查看>>
给不了你的幸福
查看>>
联系表单 1_copy
查看>>
【Qt】Qt Quick 之 QML 与 C++ 混合编程详解
查看>>
“集群和负载均衡”等的通俗解释
查看>>
matlab 中如何创建以及获取popupmenu的值
查看>>
【机器学习】多项式回归python实现
查看>>
查看cuda版本和cudann
查看>>