网络流(最大流)(小白都能看懂系列3)

网络流

网络流是啥,看的一懵一懵的,,(最难受的是摇色子又是我上去唉难受),

网络流(最大流)(小白都能看懂系列3)_第1张图片

网络流怎么做咧

网络流图是一张只有一个源点和汇点的有向图,而最大流就是求源点到汇点间的最大水流量,下图的问题就是一个最基本,经典的最大流问题

网络流(最大流)(小白都能看懂系列3)_第2张图片

二.流量,容量和可行流

对于弧(u,v)来说,流量就是其上流过的水量(我们通常用f(u,v)表示),而容量就是其上可流过的最大水量(我们通常用c(u,v)表示),只要满足f(u,v)<=c(u,v),我们就称流量f(u,v)是可行流(对于最大流问题而言,所有管道上的流量必须都是可行流)。

三.增广路

网络流(最大流)(小白都能看懂系列3)_第3张图片

最大流算法Dinic

最大流的算法有很多,有EK,Dinic,ISAP等
现在就介绍一种时间效率很高的算法–Dinic,
概念

其实EK,Dinic都有一个统一的思路–找增广路,
相信同学们在学二分图的时候已经听过这个名词,

增广路的意思是在当前网络之后找到一条能够从源点到汇点能运更多货物的路径。当一条边被增广之后(即它是增广路的一部分,或者说增广路通过这条边),这条边还能通过的流量,叫做剩余流量,修改之后的图称为残量网络。

算法步骤

Dinic算法是在找增广路 前提下加了几个优化,

先给一个步骤,后面详细解释:
1.用BFS建立分层图
2.用DFS的方法寻找一条由源点到汇点的路径,获得这条路径的流量x.
根据这条路径修改整个图,将所经之处正向边流量减少x,反向边流量增加x
重复步骤2,直到DFS找不到新的路径时,重复步骤1

DFS

在BFS之后就要从源点开始DFS找增广路,
DFS(u,exp)表示经过u点时当前流量为exp。
刚开始时从源点DFS时,exp=∞,表示从该点流出的流量可以为无限大。
在DFS中遍历u所连接的点v,dis[v]必须等于dis[u]+1,否则会多走没有必要的路径。
可以利用DFS进行多路增广来保证时间效率,即一次增广多条路。

因边有流量限制,所以DFS(u,exp)

[Math Processing Error]
当u点为T时,就等于找到一条由S点到T点的增广路,返回exp至上一层。
当u点不为T时,定义一个值flow为在u点所增广的流量,初始值为0
同时要找下一个节点以DFS(节点是一条以u为起点的边上的终点),
但需要一些限制,首先dis[v]=dis[u]+1,而且该边的剩余容量不能为0,否则肯定不能够增广更多的流量。
对于每次节点的DFS,如果该DFS可以增广的流量为0,说明增广失败,就直接跳过后面,找下一个节点v。
不为0的话,当前exp就减去增广路的流量,代表着在u点还可以流的流量,如果exp已经等于0就代表着在该点已经没有更多流量可以流过去了,必须退出增广。
flow加上该增广路增广流量。
同时,正向边减去流量,代表剩余流量,反向边加上流量(反向弧)

最后,该点所有的节点遍历完后,返回该点所增广的流量flow给上一层。

整个DFS结束后,最大流累加器ans加上S点的增广流量,因为停止了DFS,
所以已经没有路可以增广,所以重新BFS给当前残余网络建层次图。
如果BFS返回0,即S点和T点不联通时,直接退出,输出当前ans,
也就是最大流

即伪代码:

while(BFS()):
ans += DFS(S,inf)

这样,Dinic算法的步骤就结束了。

你可能感兴趣的:(网络流(最大流)(小白都能看懂系列3))