艾克斯の编码者

一个伪宅级别的码畜。

最大流(Max Flow)学习笔记 1

大纲
  1. 1. 随便写写
  2. 2. 问题提出
  3. 3. 简单思路
  4. 4. But
  5. 5. 为什么?(new)
  6. 6. 参考

好吧,在磨叽了 N 久之后,小菜我终于决定向图论进发了。为了庆祝我能稍稍理解最大流的思路,特此感谢“ACM 阿次魔”群中的各大牛们,以及白神和郭神,好吧,大牛们果然都是来自 ACM_DIY 的。ym 之。

本笔记只有思路,而且是最最入门级的思路。笔记最后附启蒙我的 PPT 下载=。=

老规矩,大牛们可以一笑而过或者选择围观,有兴趣的童鞋们可以一起研究研究。按下面按钮以阅读全文。

随便写写

所谓最大流,就是水一样哗哗哗地流过若干管道。而每个管道都有其自身的最大流量。然后你要找到从起点到终点时可以流过的最大流量。

问题提出

直接给出模型:

设定有向图 G = (V, E),每条边都有给定的容量 Cv, u,其中:s 为发点,t 为收点。对于每一点边 (v, w),最多可以有 Cv, u 个单位的流量通过。除发点和收点外,每个顶点的进入的流量必须等于发出的流量。

最大流量问题就是确定从 st 的最大流及流图。

Missing

简单思路

接下来是一个贪心(or 深搜?)的算法。即:

  1. 在残留图中找一条增长通路(从 st 的通路);
  2. 流图中加上这个通路,流量加上这条通路的最小流量的管道的权值;(最大流量是最小信道的流量,多了也流不动)
  3. 调整残留图:一旦某条管道流完了,就把管道删掉,如果没流完,那幺减去流掉的值;
  4. 一直重复 1~3 直到没有通路。

Missing

这样就得到了“最大流”。

But

很重要的一点:不好意思,以上说的只是一种思路,而不是“正确”思路。

贪心策略不能保证最优!!!

很显然,如果上述的第一条通路换成如下的通路,错误性就显而易见了:

这样一来,就阻断了 s-b-d-t 的这样一条通路,所以贪心显然是错误的。但是不能贪心,也不能随机取啊,怎幺知道要先通哪条呢?

事实上,我们只要在上面的算法中动点小手脚就好了。

在每次找到一条通路之后,删边或者减小流量之后,在这条通路的反方向加上相应的可用流量即可。就像这样:

Missing

然后就可以再找通路了,接下来的一条通路就是(蓝边):

Missing

然后我们再开始删边、加反方向可用流量,一直到没有通路为止。

为什么?(new)

为什幺要加一条回路呢?我开始不是很理解。于是我请教了 StarVae,下面是他的话:

Star VAE! 12:36:15
哦 反向边 是为了能够有后悔的机会 直接流一次 不一定就是最大流的
也就是说,反向边是为了可以让流往回流再继续下一次流的一个“过渡边”。

Star VAE! 12:38:45
流量 是加上去了的 我们算流量 不是算a->b这段路上的流量 算的是s->t这个流量 按照你的意思 如果还需要减去的话 那应该是叫做 费用 而不是流量

} **.死月| 12:39:05

} **.死月| 12:39:09
就是说 如果后悔了

} **.死月| 12:39:18
是因为有更大的通过同一条路的流量

} **.死月| 12:39:28
所以 只要加上去补差量就好了 是幺

Star VAE! 12:39:43
恩 差不多吧

参考

好吧,本小菜是看着一个《数据结构第 19 讲:第 7 章(4)最短距离,网络流》的 ppt 学的,所以本文中的图是出自于那个 ppt,以及思路也是从那里灌输过来的。

有兴趣的童鞋们可以下载。可能比我自己写的学习笔记更易懂吧。

飞速下载 PPT(原下载链接已无法寻回,但是可以自行去网上搜索)