1.什么是网络最大流

形象的来说,网络最大流其实就是这样一个生活化的问题:现在有一个由许多水管组成的水流系统,每一根管道都有自己的最大通过水流限制(流量),超过这个限制水管会爆(你麻麻就会来找你喝茶qwq)。现在,给定你一个出水口(原点),一个出水口(汇点),求这个网络中水流量的最大值。

????看起来很简单对不对?在我们看起来的确是这样的,而这部分的难点也确实不在思路上,而是在于算法设计以及代码实现上。

2.怎么求解网络最大流

首先想明白一件事情,对于一个节点来说,他接受的流量一定小于等于他给出的流量之和,否则,水管一定会爆掉。而对于一个节点来说,他接受的流量有可能大于任意一个他出边的流量,因为这个节点可以把接受流给出到不同的水管上,进而实现分流。

有了这两点,思路就很清晰了(贪心算):

1.首先,我们需要寻找一条可行的流量方案(此时,不一定为最大流量)。

2.然后我们依次扩展这条路径上的所有节点,看看这个节点是否还可以接受流量,直到已经满流。

3.重复上述步骤,直到没有可行流动路径。

4.此时我们累加的流量即为网络最大流,我们把这种方法称为最大流Dinic算法

3.实现细节

这种算法看起来简单,实际上实现起来会遇到许多小毛病,以及许多很难理解的代码实现,这里举一个栗子

在步骤2的时候我们采用dfs进行扩展,也称为网络最大流的扩展部分算法,需要借助到反边这样一个概念,即:两个节点A,B间有一条权值为w无向边。我们就把他拆分成一条由A指向B的有向边与一条由B指向A的有向边,其中,这两条边的权值之和为w,这样一来一回,两者相互抵消巧妙的实现了回溯

上代码:qwq

  1. #include<iostream>
  2. #include<cstdio>
  3. #include<cstring>
  4. #include<queue>
  5. #define N 1000005
  6. #define M 4*1000005
  7. #define INF 0xfffffff
  8.  
  9. using namespace std;
  10.  
  11. int Read()//快读
  12. {
  13. int num=0,k=1;
  14. char c=getchar();
  15. while(c!='-'&&(c<'0'||c>'9')) c=getchar();
  16. if(c=='-')
  17. {
  18. k=-1;
  19. c=getchar();
  20. }
  21. while(c<='9'&&c>='0')
  22. {
  23. num=(num<<3)+(num<<1)+c-'0';
  24. c=getchar();
  25. }
  26. return num*k;
  27. }
  28.  
  29. struct node
  30. {
  31. int from;
  32. int to;
  33. int v;
  34. int next;
  35. };
  36.  
  37. node edge[2*M];
  38. int cnt_edge=1,n,m,s,t;
  39. long long ans=0;
  40. int last[N],deep[N];
  41.  
  42. void add_edge(int u,int v,int w)
  43. {
  44. edge[++cnt_edge].from=u;
  45. edge[cnt_edge].to=v;
  46. edge[cnt_edge].v=w;
  47. edge[cnt_edge].next=last[u];
  48. last[u]=cnt_edge;
  49. }
  50.  
  51. bool bfs() //判断是否有通路
  52. {
  53. memset(deep,-1,sizeof(deep));
  54. deep[s]=0;
  55. queue<int >q;
  56. q.push(s);
  57. while(!q.empty())
  58. {
  59. int now=q.front();
  60. q.pop();
  61. for(int i=last[now];i;i=edge[i].next)
  62. {
  63. int j=edge[i].to;
  64. if(deep[j]==-1&&edge[i].v)
  65. {
  66. deep[j]=deep[now]+1;
  67. q.push(j);
  68. }
  69. }
  70. }
  71. return deep[t]!=-1;
  72. }
  73.  
  74. int dfs(int now,int flow) //flow为当前流量
  75. {
  76. if(now==t) return flow;
  77. int delta=flow; //delta是剩余流量,就是流不下去的流量
  78.  
  79. for(int i=last[now];i;i=edge[i].next)
  80. {
  81. int to=edge[i].to;
  82. if((deep[to]==(deep[now]+1))&&edge[i].v > 0)
  83. {
  84. int d=dfs(to,min(delta,edge[i].v));
  85. if(!d) deep[to] = 1e9; //剪枝优化,当前点无法下流
  86. edge[i].v-=d;edge[i^1].v+=d;delta-=d;//流下去,反边+d,方便回流
  87.  
  88. if(!delta) break;
  89. }
  90. }
  91. return flow-delta; //返回这里留下去了多少 ,即当前点的最大流量
  92. }
  93.  
  94. int main ()
  95. {
  96. n=Read();m=Read();s=Read();t=Read();
  97.  
  98. int u,v,w;
  99.  
  100. for(int i=1;i<=m;i++)
  101. {
  102. u=Read();v=Read();w=Read();
  103. add_edge(u,v,w);add_edge(v,u,0);
  104. }
  105.  
  106. while(bfs()) ans+=dfs(s,INF);
  107.  
  108. printf("%lld\n",ans);
  109. return 0;
  110. }

  看完关注哦~

网络最大流Dinic的更多相关文章

  1. P3376 【模板】网络最大流dinic算法

    P3376 [模板]网络最大流 题目描述 如题,给出一个网络图,以及其源点和汇点,求出其网络最大流. 输入输出格式 输入格式: 第一行包含四个正整数N.M.S.T,分别表示点的个数.有向边的个数.源点 ...

  2. 网络最大流 Dinic算法

    前言 看到网上好多都用的链式前向星,就我在用 \(vector\) 邻接表-- 定义 先来介绍一些相关的定义.(个人理解) 网络 一个网络是一张带权的有向图 \(G=(V,E)\) ,其中每任意一条边 ...

  3. 网络最大流dinic模板

    #include<iostream> #include<cstdio> #include<cstring> #include<queue> using ...

  4. luogu3376 【模板】网络最大流 dinic

    当前弧优化 #include <iostream> #include <cstring> #include <cstdio> #include <queue& ...

  5. P3376 【模板】网络最大流 dinic详解

    dinic的核心在于分层和多路增广. 分层的意思是,对于图用bfs搜出每一层,避免出现dfs深度过深的情况. 多路增广,利用的是dfs的回溯性质,这样就可以在一个点增广出它的所有流量. #includ ...

  6. 算法模板——Dinic网络最大流 2

    实现功能:同Dinic网络最大流 1 这个新的想法源于Dinic费用流算法... 在费用流算法里面,每次处理一条最短路,是通过spfa的过程中就记录下来,然后顺藤摸瓜处理一路 于是在这个里面我的最大流 ...

  7. 算法模板——Dinic网络最大流 1

    实现功能:同sap网络最大流 今天第一次学Dinic,感觉最大的特点就是——相当的白话,相当的容易懂,而且丝毫不影响复杂度,顶多也就是代码长个几行 主要原理就是每次用spfa以O(n)的时间复杂度预处 ...

  8. 图论算法-网络最大流【EK;Dinic】

    图论算法-网络最大流模板[EK;Dinic] EK模板 每次找出增广后残量网络中的最小残量增加流量 const int inf=1e9; int n,m,s,t; struct node{int v, ...

  9. 网络最大流算法—Dinic算法及优化

    前置知识 网络最大流入门 前言 Dinic在信息学奥赛中是一种最常用的求网络最大流的算法. 它凭借着思路直观,代码难度小,性能优越等优势,深受广大oier青睐 思想 $Dinic$算法属于增广路算法. ...

随机推荐

  1. JVM执行子程序

    Class文件结构 计算机只认识0和1,这个称之为本地机器NativeCode Jvm的无关性 与平台无关性是建立在操作系统上,虚拟机厂商提供了许多可以运行在各种不同平台的虚拟机,它们都可以载入和执行 ...

  2. pwnable——flag

    分析 此题为reverse题目,首先放入ida查看: 程序函数太少,应该加过壳 在hex view中发现程序通过upx加壳,利用upx -d 指令解压得到程序,重新放入ida查看 程序非常简单,读取f ...

  3. python3中抛异常except后面参数

    try: xxx except exception as e: print("给exception取了个别名叫做e") else: ccc

  4. [程序员代码面试指南]栈和队列-最大值减去最小值 小于或等于num 的子数组的数量(单调队列)

    题目 给定数组arr和整数num,求数组的子数组中有多少个的满足"最大值减去最小值<=num". 解题思路 分析题目,有结论: 如果数组arr[i...j]满足条件,则它的每 ...

  5. CentOS 7使用PuppeteerSharp无头浏览器注意事项

    环境: CentOS 7.6.1810 .net core 3.1 PuppeteerSharp 2.0.0 1.如网络部稳定可以提前下载需要的chromium 下载地址:https://storag ...

  6. Skywalking Php注册不上问题排查

    Skywalking是一款分布式追踪应用,具体介绍可以参考 skywalking. 最近公司的一个Php应用在Skywalking后台查不到数据了: 登录到某台服务器上发现注册不上,启动时就报错了: ...

  7. [Spring Cloud实战 | 第六篇:Spring Cloud Gateway+Spring Security OAuth2+JWT实现微服务统一认证授权

    一. 前言 本篇实战案例基于 youlai-mall 项目.项目使用的是当前主流和最新版本的技术和解决方案,自己不会太多华丽的言辞去描述,只希望能勾起大家对编程的一点喜欢.所以有兴趣的朋友可以进入 g ...

  8. redis 的基本使用

    Linux上查看redis是否运行 ps -ef | grep redis  还能查看到Linux的安装路径. set  rediskey  redisvalue  在redis里面存储了一个名称为r ...

  9. Hadoop框架:集群模式下分布式环境搭建

    本文源码:GitHub·点这里 || GitEE·点这里 一.基础环境配置 1.三台服务 准备三台Centos7服务,基础环境从伪分布式环境克隆过来. 133 hop01,134 hop02,136 ...

  10. nginx 1.12安装

    准备工作 使用root用户安装. 到nginx官网下载Linux源码或者执行:wget http://nginx.org/download/nginx-1.12.2.tar.gz. 到pcre站点下载 ...