最大流之Dinic算法
Dinic是一个分层的增广路算法。
Dinic中分层的概念定义为:到原结点的最小距离相同的点为同一层。
假设有拓扑如下:如果源点为1,宿点为4;拓扑可以分成4层。
首先,回想E-K算法是怎么算的:使用DFS在1到4之间计算一条增广路,并计算残量网络;再进行循环。我们观察计算第一次增广路(1->2->3->4)之后的残量网络,橙色的表示反向弧。
从图中可以看出,其实这个时候1->2->5->4明显还可以流过一个流量。Dinic将这些信息利用起来。如果某个层次还有可以流到下个层次的流量,就继续计算。那么在遍历到第1层的时候,除了要考虑<2,3>的容量,还要判断<2,5>的容量。
从代码级别看,在DFS时,计算了增广路径1->2->3->4之后,在回溯到2结点的时候,再继续考虑从2结点出发的下一个从1层流向2层的边(<2,5>)。具体细节可见后面代码实现。
那么,Dinic只需要一次DFS就可以实现多次增广。
Dinic算法的步骤如下:
1. 利用BFS建立分层图。
2. 在分层图中,利用DFS在拓扑中求出增广路径(相当于多条),并求出残量网络。
3. 重复步骤1,2;直到宿结点不在分层网络中,表示此时已经没有从源到宿的增广路,结束增广。
分析一下Dinic的时间复杂度:
Dinic算法进行了若干此循环,每次循环中的操作包括一次BFS和一次DFS。而这样的循环最多为V次。因此Dinic的时间复杂度为O(E*V^2)。
代码实现:
#-*- coding: utf-8 -*-# topo = {from : {to : cap}}
topo = { 1 : {2 : 5},2 : {1 : 0, 3 : 5, 5 : 5},3 : {2 : 0, 4 : 4},4 : {3 : 0, 5 : 2},5 : {2 : 0, 4 : 4}}def bfs_get_layer_net(S, D):layer_net = [0xFFFFFFFF for i in range(len(topo) + 1)]layer_net[S] = 0for src, dsts in topo.items():for dst, flow in dsts.items():if flow > 0 and layer_net[src] + 1 < layer_net[dst]:layer_net[dst] = layer_net[src] + 1return layer_net if layer_net[D] != 0xFFFFFFFF else Nonedef dfs_argument(layer_net, cur, S, D, min_flow):layer_flow = 0if D == cur : return min_flowfor dst, flow in topo[cur].items():if layer_net[cur] + 1 == layer_net[dst] and flow > 0:ans = dfs_argument(layer_net, dst, S, D, min(min_flow - layer_flow, flow))topo[cur][dst] -= anstopo[dst][cur] += anslayer_flow += ans # 重要,之后的层次进行增广的时候,最大的流量为前面的层次流下来的网络,因此在这里要进行累加。return layer_flowdef dinic(S, D):ans = 0while True:layer_net = bfs_get_layer_net(S, D)if layer_net is None: breakans += dfs_argument(layer_net, 1, 1, 4, 0xFFFFFF)return ansif __name__ == '__main__':print dinic(1, 4)
最大流之Dinic算法相关推荐
- 网络流初步:最大流(Dinic算法)
网络流初步:最大流 标签: 网络流 最大流 Dinic 最大流 例题 POJ****(USACO4.2.1) 在农夫约翰的农场上,每逢下雨,Bessie最喜欢的三叶草地就积聚了一潭水.这意味着草地被水 ...
- dinic算法 c 语言,网络流入门—用于最大流的Dinic算法
"网络流博大精深"-sideman语 一个基本的网络流问题 最早知道网络流的内容便是最大流问题,最大流问题很好理解: 解释一定要通俗! 如右图所示,有一个管道系统,节点{1,2,3 ...
- 最大流之Dinic 算法
看了http://www.cnblogs.com/SYCstudio/p/7260613.html和 https://comzyh.com/blog/archives/568/两位大佬的博客 颇有收获 ...
- 【ybt金牌导航3-2-1】【luogu P3376】网络最大流【Dinic算法】
网 络 最 大 流 网络最大流 网络最大流 题目链接:ybt金牌导航3-2-1 / luogu P3376 题目 如题,给出一个网络图,以及其源点和汇点,求出其网络最大流. 输入 第一行包含四个正整数 ...
- Dinic算法----最大流常用算法之一
--没有什么是一个BFS或一个DFS解决不了的:如果有,那就两个一起. 最大流的$EK$算法虽然简单,但时间复杂度是$O(nm^2)$,在竞赛中不太常用. 竞赛中常用的$Dinic$算法和$SAP$, ...
- 最大流EK和Dinic算法
最大流EK和Dinic算法 EK算法 最朴素的求最大流的算法. 做法:不停的寻找增广路,直到找不到为止 代码如下: @Frosero #include <cstdio> #include ...
- 图论 —— 网络流 —— 最大流 —— Dinic 算法
[概述] Dinic 算法在 EK 算法的基础上进行了优化,其时间复杂度为 O(n*n*m). Dinic 在找增广路的时也是找最短增广路, 但与 EK 算法不同的是 Dinic 算法并不是每次 bf ...
- 网络流-最大流(Ford-Fulkerson算法Dinic算法)
文章目录 最大流 FF算法: 增广路: 反边: 代码: Dinic算法: Dinic + 当前弧优化 最大流 就如同水流,存在一张图,既有起点又有终点,从起点流向终点的最大流量就是最大流. 在上面的图 ...
- 最大流算法模板:EK和dinic算法
最大流算法模板:EK和dinic算法 一.EK算法模板 #include<iostream> #include<queue> using namespace std; cons ...
最新文章
- OpenCV平滑图像Smoothing Images
- ceph集群简单安装部署(Ubuntu14环境)
- 探索Bioconductor数据包
- win10输入法简体繁体切换
- 【小知识】System.getProperties()获取系统环境变量
- 六一儿童节,看我用ModelArts让8090梦回童年
- matlab程序 surf算法,【求大神帮忙,surf算法源代码解析】
- getFullYear 方法
- python 抠图源码_别再自己抠图了,Python用5行代码实现批量抠图
- [RK3399][Android7.1] DRM中的Component System
- mysql经纬度查范围内_sql语句查询经纬度范围
- a simplest example of sql select used in excel vba
- 用opencv简单绘图
- 开美容院是否要选择加盟?
- [翻译]为EXPRESSION WEB 4添翼—如何支持HTML5设计开发!
- C++学习之boost安装及thread使用
- docker删除无用容器、镜像
- FICO配置详解之一:FI总账会计(1)
- mybatis-introduce-有传统实现类
- webp学习http://isux.tencent.com/introduction-of-webp.html