Dinic - Dinic算法(距离标号算法)


问题

用Dinic算法(也称为距离标号算法)求网络的最大流,是单源点、单汇点,边的容量都为正整数的网络。

解法

Dinic算法也是Ford–Fulkerson方法的一种实现,与Edmonds-Karp算法的区别在于增广路径的搜索方式不同。Dinic算法设计了水位图(Level Graph)/距离标号(Distance Label)来对网络进行搜索。

水位图(Level Graph)/距离图(Distance Graph):从网络的源点()出发进行BFS搜索,源点的水位/距离为,每个节点根据BFS搜索到的邻节点的水位/距离在该节点的基础上加且都相等,即(设节点是节点的BFS搜索的邻节点)。下图演示一个网络的距离图,每个节点上前一个数字为该节点的距离,后一个数字为该节点的下标:

Dinic1.png

阻塞流(Blocking Flow):增广路径中最小的剩余容量(瓶颈),其中是相邻节点,且水位差满足

Dinic算法的步骤如下:

初始化所有节点之间的流为,即(节点为相邻节点),初始化该网络的最大流为

通过BFS构建水位图;

在水位图中寻找一个阻塞流作为增广路径,更新该路径上所有边的剩余容量和最大流:

具体寻找阻塞流的方法,和Edmonds-Karp算法类似,从源点开始BFS搜索,并通过队列存储所有待搜索节点,从队列取出头节点,遍历其所有邻节点,将满足条件的加入队列中,直到找到汇点或队列为空为止。若通过BFS搜索到一条阻塞流,则更新剩余网络和最大流;若无法搜索到阻塞流,则算法结束。

可以看出Dinic算法与Edmonds-Karp算法的核心区别只在于BFS搜索的数据结构不同,Dinic算法用距离标号来限制邻节点的搜索,而Edmonds-Karp除了剩余容量以外没有其他限制。Dinic算法运行在重新构建的水位图上,边的数量比原始的网络少很多,因此搜索的时间复杂度大大降低。

该算法的时间复杂度为


Dinic Algorithm


源码

Dinic.h

Dinic.cpp

测试

DinicTest.cpp