网络流 (一) 最大流的原理图解
2017-12-09 15:09
162 查看
嗯…于是学一波网络流罢
之前学过一波,不过失败了orz
希望这次能学成功(x)
绿色的边表示桥,上面的数字表示载重。
老板打算从A到G。
显然,作为一个老板,超载是不合适的,姑且不论货物安全,还有可能受到法律惩罚!那么,最多能一次载多少货物呢?
在解决这个问题之前,我们先为这一模型定义一些概念。
出发点成为源点,也就是A,显然,该点入度为0
终点称为汇点,也就是G,显然,该点出度为0
而每条边上的最大载重称为容量,例如CD边的容量是6。引入符号c[i,j]表示从节点i到节点j的容量;在实际问题中,一条边不一定必须达到载重,一个载重6t的路放4t的货车运输,那么我们就称4是这条路的流量。引入符号f[i,j]表示节点i到节点j的容量。
显然,由于不可能超过限重,f[i,j]<=c[i,j]恒成立。
并且,货物显然不能损失吧,所以源点和汇点的流量是相同的,对于所有点,流入的流量和流出是相同的。
建模完成,接下来就是求解了。
黄色的代表一个可行流,其中数字第一个表示容量,第二个为流量。
我们知道,零流就是一个典型代表——毕竟,它并不会超过容量。
然后,我们就可以开始增广操作了。其实增广是一种自然而然的想法:假定路径s是当前的流,并且,这条路径还可以拓展,那么我们就试图去塞进去更多的流。
这样说不是很明白,举个栗子(为了方便我画图起见我们姑且换一个图)来演示一下过程好了。
好的,现在先yy一下图中存在0流。这里我们写了一个东西叫做剩余,表示的是当前这中方式下还有多少流能够汇入。
那么,增广开始。不妨采用BFS的思想,第一次找到了路径A−B−C
我们发现,这条路线上最多能增广2单位的流,所以我们将流注入。
图中的n/m表示流量/容量
此时变成了这种样子。然后我们仍然BFS,发现了A−B−D−C这条路径。这条路径上最多能增广一个单位的流,于是增长之。
没毛病!然后再去增广A−D−C这条路,结果发现,可以增长三个单位的流。增长之:
扫视一遍,发现未有能增广者,结束增广。
完成了,可喜可贺。由于源点和汇点的流量相同,我们知道,最大流就是6个单位。为之四顾,为之踌躇满志。
但是,在你跃跃欲试去写网络流模板之前,不得不先泼一瓢凉水——
如果此时BFS没有去增广A−B−C,而是先增广了A−B−D−C呢?这个时候,我们再来看看情况:
(上面的CD应该剩余1,写错了)
继续:
惊悚的事情发生了。
没错,之后没有办法增广了,但是!此时我们求出的最大流是4!
这是否证明我们的贪心思路是错的呢?
机制的珂学家们引入了下面的概念,完美的回避掉了这个致命的漏洞——
怎么搞呢?我们可以每增广一次,就建立一条反向边。
仍然是上面的例子,在对A−B−C−D增广之后如下图。
注意,这里的A′B′C′D′并不是虚点,而是ABCD本身,这里只是为了方便画图和观察所以分开画了。
然后呢——我们发现,A−D−B−C变得可增广了,也就是,A−D,D′B′,BC这条。那么我们对它进行增广之后:
这个图可能稍微有些乱,红色的是我们增广的东西,绿色是增广建的反向边。
当然,继续扫一遍,发现A−D−C还可以增广,于是最后的结果:
没有可以增广的了——完成DAZE!
所以最终的结果就是6。
那么可能有人会问了——上面我们走了A−D−B−C这条原本不应该存在的路,意义是什么呢?其实,这相当我们把原本贪心走BD这条路的流逼了回去,转而走BC。
上面就是一切网络流问题的基础,也是最大流的原理。下一篇文章,我们考虑其实现办法。
http://blog.csdn.net/xiaoxin_ling/article/details/19970179
之前学过一波,不过失败了orz
希望这次能学成功(x)
建模
想象一下,你在调度货车运输(不是最小生成树+LCA那道题放心吧),但是有些桥是有载重限制的。比如下图:绿色的边表示桥,上面的数字表示载重。
老板打算从A到G。
显然,作为一个老板,超载是不合适的,姑且不论货物安全,还有可能受到法律惩罚!那么,最多能一次载多少货物呢?
在解决这个问题之前,我们先为这一模型定义一些概念。
出发点成为源点,也就是A,显然,该点入度为0
终点称为汇点,也就是G,显然,该点出度为0
而每条边上的最大载重称为容量,例如CD边的容量是6。引入符号c[i,j]表示从节点i到节点j的容量;在实际问题中,一条边不一定必须达到载重,一个载重6t的路放4t的货车运输,那么我们就称4是这条路的流量。引入符号f[i,j]表示节点i到节点j的容量。
显然,由于不可能超过限重,f[i,j]<=c[i,j]恒成立。
并且,货物显然不能损失吧,所以源点和汇点的流量是相同的,对于所有点,流入的流量和流出是相同的。
建模完成,接下来就是求解了。
增广
首先,我们定义一种合理的载重方法为可行流。比如下图:黄色的代表一个可行流,其中数字第一个表示容量,第二个为流量。
我们知道,零流就是一个典型代表——毕竟,它并不会超过容量。
然后,我们就可以开始增广操作了。其实增广是一种自然而然的想法:假定路径s是当前的流,并且,这条路径还可以拓展,那么我们就试图去塞进去更多的流。
这样说不是很明白,举个栗子(为了方便我画图起见我们姑且换一个图)来演示一下过程好了。
好的,现在先yy一下图中存在0流。这里我们写了一个东西叫做剩余,表示的是当前这中方式下还有多少流能够汇入。
那么,增广开始。不妨采用BFS的思想,第一次找到了路径A−B−C
我们发现,这条路线上最多能增广2单位的流,所以我们将流注入。
图中的n/m表示流量/容量
此时变成了这种样子。然后我们仍然BFS,发现了A−B−D−C这条路径。这条路径上最多能增广一个单位的流,于是增长之。
没毛病!然后再去增广A−D−C这条路,结果发现,可以增长三个单位的流。增长之:
扫视一遍,发现未有能增广者,结束增广。
完成了,可喜可贺。由于源点和汇点的流量相同,我们知道,最大流就是6个单位。为之四顾,为之踌躇满志。
但是,在你跃跃欲试去写网络流模板之前,不得不先泼一瓢凉水——
如果此时BFS没有去增广A−B−C,而是先增广了A−B−D−C呢?这个时候,我们再来看看情况:
(上面的CD应该剩余1,写错了)
继续:
惊悚的事情发生了。
没错,之后没有办法增广了,但是!此时我们求出的最大流是4!
这是否证明我们的贪心思路是错的呢?
机制的珂学家们引入了下面的概念,完美的回避掉了这个致命的漏洞——
反向弧
既然这么贪不一定是对的,那么我们就可以引入一种后悔机制,来提供反悔的机会。怎么搞呢?我们可以每增广一次,就建立一条反向边。
仍然是上面的例子,在对A−B−C−D增广之后如下图。
注意,这里的A′B′C′D′并不是虚点,而是ABCD本身,这里只是为了方便画图和观察所以分开画了。
然后呢——我们发现,A−D−B−C变得可增广了,也就是,A−D,D′B′,BC这条。那么我们对它进行增广之后:
这个图可能稍微有些乱,红色的是我们增广的东西,绿色是增广建的反向边。
当然,继续扫一遍,发现A−D−C还可以增广,于是最后的结果:
没有可以增广的了——完成DAZE!
所以最终的结果就是6。
那么可能有人会问了——上面我们走了A−D−B−C这条原本不应该存在的路,意义是什么呢?其实,这相当我们把原本贪心走BD这条路的流逼了回去,转而走BC。
上面就是一切网络流问题的基础,也是最大流的原理。下一篇文章,我们考虑其实现办法。
参考Blog
https://www.cnblogs.com/ZJUT-jiangnan/p/3632525.htmlhttp://blog.csdn.net/xiaoxin_ling/article/details/19970179
相关文章推荐
- POJ 1087 A Plug for UNIX(网络流—最大流(最大二分匹配))
- 第十一周项目9知原理二叉树的构造(图解)
- 瀚海拾贝(一)HTTP协议/IIS 原理及ASP.NET运行机制浅析【图解】
- 网络流入门—用于最大流的Dinic算法
- hdu 1532 Drainage Ditches(最大网络流)
- 图论最大网络流增广路算法详解与实现
- ★ 最长递增子序列问题 (最多不相交路径)(分层思想) 网络流最大流
- 机器学习算法原理与实践(二)、meanshift算法图解以及在图像聚类、目标跟踪中的应用
- hdu5855Less Time, More profit【网络流 最大权闭合图】2016多校联合第九场
- 图解mapreduce原理和执行过程
- poj 1459 Power Network(网络流 最大流 dinic模板题)
- POJ2112 Optimal Milking—网络流,最大流,二分
- HDU 3338 - Kakuro Extension(网络流‘最大流)
- 【网络流#6】POJ 3041 Asteroids 二分图最大匹配 - 《挑战程序设计竞赛》例题
- HDU 3605 Escape (网络流,最大流,位运算压缩)
- 网络流(最大流,最小割)基础入门详解
- 网络流最大流算法(ISAP算法及DINIC算法)
- bzoj3504 [Cqoi2014]危桥 (网络流 最大流)
- php对象的拷贝原理(附图解)
- Activity间数据传输原理图解