[讲解]网络流最大流dinic算法
网络流最大流算法dinic
ps:本文章不适合萌新,我写这个主要是为了复习一些细节,概念介绍比较模糊,建议多刷题去理解
例题:codevs草地排水,方格取数
【抒情一下】
虽然老师说这个多半不考,但是学了没坏处,所以我就把这算法学了(准确说是补起了QAQ)
以前一直觉得dinic的代码好长好难啊,然后就知难而退
最近学了很多和看了很多以后,咱们就学会了知男♂而上了,所以我果断的回来上dinic了
【dinic】
Dinic算法是用来做最大流一类题的,代码有一丢丢的长,但其实说白了就是一个bfs+dfs就没了,所以没必要有啥心理负担

我们先来画一个图,我们需要从1点流到n点
首先看这个图,每条边上标的是这条边的容量
Dinic的想法就是对当前图去找一条还能够从s通往t的可行路
然后可行路可以由图中的边组成,也可以用图中的边的逆向边组成
至于为什么要建立逆向边和逆向边的含义,我们重新画一张图

我假设这张图的目前的流量为
E(s,2)=0,E(s,1)=4,E(1,2)=2,E(2,t)=2,E(1,t)=2;
然后我们建立逆向边或者说是反向弧,就是沿着箭头的反方向建边,反向边的容量为正向边的流量(不是容量)
所以当前反向边的容量为
E(2,s)=0,E(1,s)=4,E(2,1)=2,E(t,2)=2,E(t,1)=2;
然后为什么要建立这些边,我们先看图,当前的图肯定不是最优的,这时候就要找增广路
增广路简单一点理解就是还有一条从s到t的路
然后我们发现边s,1是满的,所以找到可以流的边s,2的流量是0,然后到2点发现2,1边的容量是2(因为E(1,2)=2,所以反向此时的容量为2),最后发现1,t边容量4流量2,于是找到一条增广路
S->2->1->t,这条增广路可以扩大2的流量,所以最大流+2,为6
至于程序也很简单,首先是建图,建完图以后一个while循环(用bfs判断),bfs的过程是找还有没有增广路,然后在循环内dfs,dfs是找这条增广路的可以扩大的最大流量
至于在dfs判断是否是我们找出的合法路径,可以在bfs是对路径加深度,如果容量大于流量并且不是同一深度,那么dfs就可以继续搜索下去
然后我给一个dinic的模版,模板题就用草地排水了
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<iostream>
#include<queue>
#include<cmath>
#include<cstdlib>
#include<stack>
#define maxn 505
using namespace std; queue<int>q;
int c[maxn],head[maxn],f[maxn],n,m,dep[maxn],ans;
struct edge{
int u,v,w,nxt,flow;
}e[maxn]; int read(){
int xx=,ff=;char ch=getchar();
while(ch<''||ch>''){if(ch=='-')ff=-;ch=getchar();}
while(ch>=''&&ch<=''){xx=xx*+ch-'';ch=getchar();}
return xx*ff;
} int tot=;
void adde(int u,int v,int w){
e[++tot].u=u;
c[tot]=w;
e[tot].v=v;e[tot].w=w;
e[tot].nxt=head[u];
head[u]=tot;
} int bfs(){
q.push();
memset(dep,-,sizeof(dep));
dep[]=;
while(!q.empty()){
int u=q.front();q.pop();
for(int i=head[u];i!=-;i=e[i].nxt){
int v=e[i].v;
if(dep[v]==-&&c[i]-f[i]){
dep[v]=dep[u]+;
q.push(v);
}
}
}
if(dep[n]==-)return ;
else return ;
} int dfs(int u,int lim){
if(u==n){ans+=lim;return lim;}
int t;
for(int i=head[u];i!=-;i=e[i].nxt ){
int v=e[i].v;
if(c[i]-f[i]&&dep[u]+==dep[v]&&(t=dfs(v,min(lim,c[i]-f[i])))){
f[i]+=t;f[i^]-=t;return t;
}
}
return ;
} int main(){
memset(head,-,sizeof(head));
m=read();n=read();
for(int i=;i<=m;i++){
int u,v,w;
u=read();v=read();w=read();
adde(u,v,w);adde(v,u,);
}
while(bfs()){
dfs(,0x3f3f3f);
}
printf("%d",ans);
}
【总结】
网络流的难点在于建图,这个另类的建图可以参加一下方格取数,拓宽一下视野
[讲解]网络流最大流dinic算法的更多相关文章
- 网络流最大流——dinic算法
前言 网络流问题是一个很深奥的问题,对应也有许多很优秀的算法.但是本文只会讲述dinic算法 最近写了好多网络流的题目,想想看还是写一篇来总结一下网络流和dinic算法以免以后自己忘了... 网络流问 ...
- Power Network(网络流最大流 & dinic算法 + 优化)
Power Network Time Limit: 2000MS Memory Limit: 32768K Total Submissions: 24019 Accepted: 12540 D ...
- 网络流——最大流Dinic算法
前言 突然发现到了新的一年什么东西好像就都不会了凉凉 算法步骤 建残量网络图 在残量网络图上跑增广路 重复1直到没有增广路(注意一个残量网络图要尽量把价值都用完,不然会浪费建图的时间) 代码实现 #i ...
- 网络流之最大流Dinic算法模版
/* 网络流之最大流Dinic算法模版 */ #include <cstring> #include <cstdio> #include <queue> using ...
- 网络流(最大流-Dinic算法)
摘自https://www.cnblogs.com/SYCstudio/p/7260613.html 网络流定义 在图论中,网络流(Network flow)是指在一个每条边都有容量(Capacity ...
- 学习笔记 --- 最大流Dinic算法
为与机房各位神犇同步,学习下网络流,百度一下发现竟然那么多做法,最后在两种算法中抉择,分别是Dinic和ISAP算法,问过 CA爷后得知其实效率上无异,所以决定跟随Charge的步伐学习Dinic,所 ...
- hdu-3572 Task Schedule---最大流判断满流+dinic算法
题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=3572 题目大意: 给N个任务,M台机器.每个任务有最早才能开始做的时间S,deadline E,和持 ...
- (通俗易懂小白入门)网络流最大流——EK算法
网络流 网络流是模仿水流解决生活中类似问题的一种方法策略,来看这么一个问题,有一个自来水厂S,它要向目标T提供水量,从S出发有不确定数量和方向的水管,它可能直接到达T或者经过更多的节点的中转,目前确定 ...
- 最大流——Dinic算法
前面花了很长时间弄明白了压入-重标记的各种方法,结果号称是O(V3)的算法测demo的时候居然TLE了一个点,看了题解发现所有人都是用Dinic算法写的,但它的复杂度O(V2E)明显高于前者,具体是怎 ...
随机推荐
- java线程间的协作
本次内容主要讲等待/通知机制以及用等待/通知机制手写一个数据库连接池. 1.为什么线程之间需要协作 线程之间相互配合,完成某项工作,比如:一个线程修改了一个对象的值,而另一个线程感知到了变化,然后进行 ...
- 日常破解--从XCTF的app3题目简单了解安卓备份文件以及sqliteCipher加密数据库
一.题目来源 题目来源:XCTF app3题目 二.解题过程 1.下载好题目,下载完后发现是.ab后缀名的文件,如下图所示: 2.什么是.ab文件?.ab后缀名的文件是Andr ...
- 网址封锁的几种方法 公司把 pan.baidu.com 封了 研究实现原理
HTTP 和 HTTPS 协议HTTP 协议在 头部会发送 host 就是要访问的域名,可以用来被检测. HTTPS 协议虽然会加密全部通讯,但是在握手之前还是明文传输.有证书特证可被检测. 1, D ...
- Java自学路线图之Java基础自学
自学Java要从Java基础语法开始自学,自学Java的过程中打好基础是很重要的!首先自学:面向对象基础,API基础,集合基础.这些对Java小白的数学和英语能力的要求门槛不高,在学习的过程中积累相应 ...
- 谈谈SQL优化
写SQL是学习数据库必须掌握的非常重要的技能之一.在学习过程当中,我们会尝试写各种各样满足需求的SQL语句.在实际项目中,优秀的SQL语句和普通的SQL语句的执行速度差别非常大.对于一个数据量很大的系 ...
- 雅奇880、990、小土豆调用EPX Studio 编译的DLL的编程方法~
在雅奇990中,使用“外部文件-调用链接库文件”命令实现与EP的通信,例如: 1.调用链接库文件(取项目文件信息() + '资源文件\Project1.dll', 'Unit1.rpas:Result ...
- DOTNET CORE源码分析之ServiceDescriptor
ServiceDescriptor在.net core中的作用就是DI中注入服务元素的描述.每一个元素核心内容部分包括需要注入的服务元素的类型ServiceType,它对应的接口(如果有的话)Impl ...
- WEB应用之httpd基础入门(一)
前文我们聊了下http协议web服务的一些常识和httpd服务器软件三种响应模型的简单介绍,回顾请参考https://www.cnblogs.com/qiuhom-1874/p/12515075.ht ...
- Mybatis(二) Mybatis通用的写法
2.1 用来循环容器的标签forEach,查看例子 foreach元素的属性主要有item,index,collection,open,separator,close. item:集合中元素迭代时 ...
- 面试话痨(二)C:JAVA String,别以为你穿个马甲我就不认识你了
面试话痨系列是从技术广度的角度去回答面试官提的问题,适合萌新观看! 面试官,别再问我火箭怎么造了,我知道螺丝的四种拧法,你想听吗? String相关的题目,是面试中经常考察的点,当面试中遇到了St ...