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算法相关推荐

  1. 网络流初步:最大流(Dinic算法)

    网络流初步:最大流 标签: 网络流 最大流 Dinic 最大流 例题 POJ****(USACO4.2.1) 在农夫约翰的农场上,每逢下雨,Bessie最喜欢的三叶草地就积聚了一潭水.这意味着草地被水 ...

  2. dinic算法 c 语言,网络流入门—用于最大流的Dinic算法

    "网络流博大精深"-sideman语 一个基本的网络流问题 最早知道网络流的内容便是最大流问题,最大流问题很好理解: 解释一定要通俗! 如右图所示,有一个管道系统,节点{1,2,3 ...

  3. 最大流之Dinic 算法

    看了http://www.cnblogs.com/SYCstudio/p/7260613.html和 https://comzyh.com/blog/archives/568/两位大佬的博客 颇有收获 ...

  4. 【ybt金牌导航3-2-1】【luogu P3376】网络最大流【Dinic算法】

    网 络 最 大 流 网络最大流 网络最大流 题目链接:ybt金牌导航3-2-1 / luogu P3376 题目 如题,给出一个网络图,以及其源点和汇点,求出其网络最大流. 输入 第一行包含四个正整数 ...

  5. Dinic算法----最大流常用算法之一

    --没有什么是一个BFS或一个DFS解决不了的:如果有,那就两个一起. 最大流的$EK$算法虽然简单,但时间复杂度是$O(nm^2)$,在竞赛中不太常用. 竞赛中常用的$Dinic$算法和$SAP$, ...

  6. 最大流EK和Dinic算法

    最大流EK和Dinic算法 EK算法 最朴素的求最大流的算法. 做法:不停的寻找增广路,直到找不到为止 代码如下: @Frosero #include <cstdio> #include ...

  7. 图论 —— 网络流 —— 最大流 —— Dinic 算法

    [概述] Dinic 算法在 EK 算法的基础上进行了优化,其时间复杂度为 O(n*n*m). Dinic 在找增广路的时也是找最短增广路, 但与 EK 算法不同的是 Dinic 算法并不是每次 bf ...

  8. 网络流-最大流(Ford-Fulkerson算法Dinic算法)

    文章目录 最大流 FF算法: 增广路: 反边: 代码: Dinic算法: Dinic + 当前弧优化 最大流 就如同水流,存在一张图,既有起点又有终点,从起点流向终点的最大流量就是最大流. 在上面的图 ...

  9. 最大流算法模板:EK和dinic算法

    最大流算法模板:EK和dinic算法 一.EK算法模板 #include<iostream> #include<queue> using namespace std; cons ...

最新文章

  1. OpenCV平滑图像Smoothing Images
  2. ceph集群简单安装部署(Ubuntu14环境)
  3. 探索Bioconductor数据包
  4. win10输入法简体繁体切换
  5. 【小知识】System.getProperties()获取系统环境变量
  6. 六一儿童节,看我用ModelArts让8090梦回童年
  7. matlab程序 surf算法,【求大神帮忙,surf算法源代码解析】
  8. getFullYear 方法
  9. python 抠图源码_别再自己抠图了,Python用5行代码实现批量抠图
  10. [RK3399][Android7.1] DRM中的Component System
  11. mysql经纬度查范围内_sql语句查询经纬度范围
  12. a simplest example of sql select used in excel vba
  13. 用opencv简单绘图
  14. 开美容院是否要选择加盟?
  15. [翻译]为EXPRESSION WEB 4添翼—如何支持HTML5设计开发!
  16. C++学习之boost安装及thread使用
  17. docker删除无用容器、镜像
  18. FICO配置详解之一:FI总账会计(1)
  19. mybatis-introduce-有传统实现类
  20. webp学习http://isux.tencent.com/introduction-of-webp.html

热门文章

  1. java race condition_Java中的Race condition和Critical section(译)
  2. 网站导航:如何在线生成自定义的二维码?(要美观不要俗气)
  3. Jenkins 构建CI/CD(一看就会)
  4. 机器人10大流行编程语言
  5. [Android]如何做一个崩溃率少于千分之三噶应用app(31)-组件化网络请求
  6. 致敬 互联网背后的运维工程师们
  7. CyberGhost使用、下载、注册【完整教程】
  8. gdal_遥感影像配准
  9. AutoLisp从入门到放弃(十七)
  10. 漏洞挖掘之乱拳打死老师傅——Fuzzer