博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
最大流
阅读量:5051 次
发布时间:2019-06-12

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

最大流

网络流问题

给定指定的一个有向图,其中有两个特殊的点源S(Sources)和汇T(Sinks),每条边有指定的容量(Capacity),求满足条件的从S到T的最大流(MaxFlow)。

显然有流网络有三个性质:1.容量限制:流量不会大于容量。2.反对称性:从u到v的流量一定是从v到u流量的相反值。3.流守恒性:流入与流出相同。这里要特意注意第二条,一条边上的流量v会带来反向的流量c-v,具体体现在代码,就是在残留网络中每条边都有反边,当一条边的流量增加,它的反边的流量就减少相应值。网络流的算法就是基于残留网络而不是基于原网络的。

残留网络,增广路和割

增广路就是一条通过残留网络的流,其作用是“反悔”。割C[A, B]是将图G分为A和B两个点集,使得S在A中,T在B中。注意所谓“割中的边”,指的是从属于S的点出发,到T的所有边。

如何求出一个网络的最大流呢?有一个最简单的EK算法,思路是每次找出一条增广路,不断调整残留网络,直到没有增广路为止。这个证明可以感性愉悦一下。下面是理性不愉悦的 。

对于一个网络流图G=(V,E),其中有源点s和汇点t,那么下面三个条件是等价的:

  1. 流f是图G的最大流
  2. 残留网络Gf不存在增广路
  3. 对于G的某一个割(S,T),此时f = C(S,T)

首先证明1 => 2:

我们利用反证法,假设流f是图G的最大流,但是残留网络中还存在有增广路p,其流量为fp。则我们有流f'=f+fp>f。这与f是最大流产生矛盾。

接着证明2 => 3:

假设残留网络Gf不存在增广路,所以在残留网络Gf中不存在路径从s到达t。我们定义S集合为:当前残留网络中s能够到达的点。同时定义T=V-S。

此时(S,T)构成一个割(S,T)。且对于任意的u∈S,v∈T,有f(u,v)=c(u,v)。若f(u,v)<c(u,v),则有Gf(u,v)>0,s可以到达v,与v属于T矛盾。

因此有f(S,T)=Σf(u,v)=Σc(u,v)=C(S,T)。

最后证明3 => 1:

由于f的上界为最小割,当f到达割的容量时,显然就已经到达最大值,因此f为最大流。

这样就说明了为什么找不到增广路时,所求得的一定是最大流,大概思想就是利用割作为跳板来证明。

Dinic

我们来算一下EK的复杂度。首先我们定义层次图。将残留网络从s开始bfs,计算出每个点是第几层的,层次图中只包含从层次低连到高的边。将t的层数定义为层次图的层数。相同层数的层次图称为一个阶段。

设原残留网络的层数为k。容易发现增广一次,k要么不变,要么增加。k增加的原因是增广是在层次图上增广的,不会使层次图中的边流量增加,只会增加后向边的流量,因此bfs会走更多的回头路,层数随之增加。(此处感性愉悦,具体见)

因此随着增广,层次图的层数严格递增。由于最短路的长度最少为1,最多为n-1,所以最多有n-1个阶段,近似于n。在同一阶段中,每增广一次,就会至少减少一条层次图中的边。所以最多增广m次。而EK算法找增广路用的bfs,所以时间复杂度为O(n*m^2)。

Dinic唯一做的就是把bfs改成dfs。在每一个阶段中,先用一个bfs将所有的点的层次都确定出来,然后强制dfs只能从层次浅的跑向深的点。这样就可以用dfs代替bfs了。时间复杂度被优化到O(n^2*m),考场上一般写这个。

注意我加了一个当前弧优化,就是dfs时不用跑已经跑过的弧了,因为边的流量只会少不会多,并且层次图是个dag。

#include 
#include
#include
using namespace std;const int maxf=55, maxn=maxf*200, maxm=maxn+100, INF=1e9, inf=1e8;int n, m, cnt, src, dst, ans;inline int min(int x, int y){ return x
r[u]) continue; //beg[u]+j-l[u]表示x[u]=x[v]+d的点的编号 addedge(max(beg[u], beg[u]+j-l[u]), beg[v]+i-l[v], 2*inf); } } printf("%d\n", inf*n-Dinic()); return 0;}

至于sap。。反正我是不准备学了(不会用到.jpg)

转载于:https://www.cnblogs.com/MyNameIsPc/p/8964449.html

你可能感兴趣的文章
返回代码hdu 2054 A==B?
查看>>
Flink独立集群1
查看>>
iOS 8 地图
查看>>
20165235 第八周课下补做
查看>>
[leetcode] 1. Two Sum
查看>>
iOS 日常工作之常用宏定义大全
查看>>
PHP的SQL注入技术实现以及预防措施
查看>>
MVC Razor
查看>>
软件目录结构规范
查看>>
Windbg调试Sql Server 进程
查看>>
linux调度器系列
查看>>
mysqladmin
查看>>
解决 No Entity Framework provider found for the ADO.NET provider
查看>>
SVN服务器搭建和使用(三)(转载)
查看>>
Android 自定义View (三) 圆环交替 等待效果
查看>>
设置虚拟机虚拟机中fedora上网配置-bridge连接方式(图解)
查看>>
HEVC播放器出炉,迅雷看看支持H.265
查看>>
[置顶] Android仿人人客户端(v5.7.1)——人人授权访问界面
查看>>
Eclipse 调试的时候Tomcat报错启动不了
查看>>
【安卓5】高级控件——拖动条SeekBar
查看>>