【网络流相关】最大流的Dinic算法实现
Luogu P3376
由于\(EK\)算法求最大流时每一次只求一条增广路,时间复杂度会比较高。尽管实际应用中表现比较优秀,但是有一些题目还是无法通过。
那么我们就会使用\(Dinic\)算法实现多路增广。
算法的基本流程如下:
- \(BFS\)对图进行分层,求出终点所在的层数
- \(DFS\)对每一条增广路的信息进行更新
仅仅这样看,虽然一次\(BFS\)能找到多条最短增广路,但是信息的更新仍然是逐条增广路进行更新,效率上并没有太大变化。
所以我们需要下面的两个优化:
- 记录起点到节点\(P\)的流\(flow\)和节点\(P\)到终点的流\(used\)。若\(flow=used\),则不必再进行之后的\(DFS\)了,可以直接回溯。
- 使用一个\(cur\)数组复制链式前向星的\(head\)数组,在\(DFS\)时,\(cur\)数组记录当前处理的边的编号。下次\(DFS\)到这个节点时,可以直接从\(cur\)数组记录的那条边开始。
第二个优化我们称之为当前弧优化。
原理:每一条已经处理完毕的边,必然不能再容纳下更多的流了。
\(Dinic\)的时间复杂度是\(O(n^2m)\)。对于二分图匹配问题,\(Dinic\)的时间复杂度是\(O(m\sqrt n)\)
结合代码进行理解
#include<cstdio>
#include<queue>
using namespace std;
int n,m,num,cnt,u,v,head[20005],cur[20005],dis[20005],ans;
bool vis[20005];
struct data
{
int to,next,val;
}e[5000005];
void add(int u,int v,int val)
{
e[++cnt].to=v;
e[cnt].next=head[u];
head[u]=cnt;
e[cnt].val=val;
}
bool bfs(int s,int t)
{
queue<int> que;
que.push(s);
for (int i=1;i<=n;i++) dis[i]=0,vis[i]=false,cur[i]=head[i];
vis[s]=true;
dis[s]=1;
while (!que.empty())
{
int now=que.front();
que.pop();
for (int i=head[now];i;i=e[i].next)
{
v=e[i].to;
if (!vis[v]&&e[i].val>0)
{
dis[v]=dis[now]+1;
vis[v]=true;
if (v==t) return true;
que.push(v);
}
}
}
return false;
}
int dfs(int now,int t,int flow)
{
if (!flow||now==t) return flow;
int used=0;
for (int i=cur[now];i;i=e[i].next)
{
cur[now]=i;//当前弧优化
v=e[i].to;
if (dis[now]+1!=dis[v]) continue;
int tmp=dfs(v,t,min(flow-used,e[i].val));
if (tmp)
{
e[i].val-=tmp;
e[i^1].val+=tmp;
used+=tmp;
if (flow-used==0) return flow;
}
}
return used;
}
void Dinic(int s,int t)
{
while (bfs(s,t)) ans+=dfs(s,t,0x7fffffff);
}
int main()
{
int s,t,w;
scanf("%d%d%d%d",&n,&m,&s,&t);
cnt=1;
for (int i=1;i<=m;i++)
{
scanf("%d%d%d",&u,&v,&w);
add(u,v,w);
add(v,u,0);
}
Dinic(s,t);
printf("%d",ans);
return 0;
}
【网络流相关】最大流的Dinic算法实现的更多相关文章
- 网络流入门—用于最大流的Dinic算法
"网络流博大精深"-sideman语 一个基本的网络流问题 最早知道网络流的内容便是最大流问题,最大流问题很好理解: 解释一定要通俗! 如右图所示,有一个管道系统,节点{1,2,3 ...
- 【最大流之Dinic算法】POJ1273 【 & 当前弧优化 & 】
总评一句:Dinic算法的基本思想比较好理解,就是它的当前弧优化的思想,网上的资料也不多,所以对于当前弧的优化,我还是费了很大的功夫的,现在也一知半解,索性就写一篇博客,来发现自己哪里的算法思想还没理 ...
- 浅谈最大流的Dinic算法
PART 1 什么是网络流 网络流(network-flows)是一种类比水流的解决问题方法,与线性规划密切相关.网络流的理论和应用在不断发展,出现了具有增益的流.多终端流.多商品流以及网络流的分解与 ...
- HDU1532最大流 Edmonds-Karp,Dinic算法 模板
Drainage Ditches Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others) To ...
- POJ 1459 Power Network(网络最大流,dinic算法模板题)
题意:给出n,np,nc,m,n为节点数,np为发电站数,nc为用电厂数,m为边的个数. 接下来给出m个数据(u,v)z,表示w(u,v)允许传输的最大电力为z:np个数据(u)z,表示发电 ...
- [模板] 网络流相关/最大流ISAP/费用流zkw
最大流/ISAP 话说ISAP是真快...(大多数情况)吊打dinic,而且还好写... 大概思路就是: 在dinic的基础上, 动态修改层数, 如果终点层数 \(>\) 点数, break. ...
- 最大流:Dinic算法
蒟蒻居然今天第一次写网络流 我太弱啦! 最大流问题有很多解法 虽然isap常数巨小 但是连dinic都写挂的本蒟蒻并不会orz 那么我们选用比较好实现的dinic来解决最大流问题 来一段定义: ...
- POJ 1459 Power Network / HIT 1228 Power Network / UVAlive 2760 Power Network / ZOJ 1734 Power Network / FZU 1161 (网络流,最大流)
POJ 1459 Power Network / HIT 1228 Power Network / UVAlive 2760 Power Network / ZOJ 1734 Power Networ ...
- 网络流最大流——dinic算法
前言 网络流问题是一个很深奥的问题,对应也有许多很优秀的算法.但是本文只会讲述dinic算法 最近写了好多网络流的题目,想想看还是写一篇来总结一下网络流和dinic算法以免以后自己忘了... 网络流问 ...
随机推荐
- 千与千寻主题曲beep函数版
在出代码之前,我们向来了解一下Beep函数. 例: Beep(,); 这个表示575Hz响100ms. 下面给出代码: #include <bits/stdc++.h> #include ...
- python3学习,有c++的基础
# 为注释一行 ''' ''' 和 """ """为注释多行 用缩进表示代码块,不用{},同一等级代码用的缩进数一致 一条语句写在多行:a= ...
- DHCP动态管理主机地址
步骤一:搭建环境 需要Windows 2008 R2 系统 (DHCP服务端)以及 CentOS7 系统客户机(DHCP客户机) 安装DHCP服务程序(这里提示读者,一般安装好CentOS系统之后, ...
- C语言:大数取余
大数取余数(数组) 今天做学校的oj时遇到一题,问题可见一下截图: 查遍各大论坛,都没有遇到合适的方法,普通方法不可用,要采用数组的形式. 被除数超过long long类型,不能采用常规思路,否则会出 ...
- 2019年PHP面试题附答案(实战经验)
出于一些原因近期做了一次工作变动,在职交接近一个半月时间大概面试了十五家公司,并且得到了自己比较满意的offer,最后基本上无缝衔接了新工作.总体来说,虽然准备的很充分,但面试期间还是暴露了许多问题, ...
- 公众号第三方平台开发 component_verify_ticket和accessToken的获取
公众号第三方平台审核通过之后,微信的服务器会定时(10分钟一次)给"授权事件接收URL"发送component_verify_ticket,这里我们需要及时更新component_ ...
- HTML 颜色输入框修改事件的触发,以及获取修改后的颜色
HTML 颜色输入框修改事件的触发,以及获取修改后的颜色 <!DOCTYPE html> <html lang="en"> <head> < ...
- 802.11r协议理解
首先阅读了相关协议内容整理出了如下的802.11r时序图所谓基础,然后会详细理解其中的每一个步骤:
- Arduino驱动ILI9341彩屏(一)——颜色问题
最近在淘宝的店铺上淘到了一块ILI9341的彩色液晶屏,打算研究一下如何使用. 淘宝店铺购买屏幕之后有附源代码可供下载,代码质量惨不忍睹,各种缩进不规范就不说了,先拿来试一下吧. 这是淘宝店铺代码的核 ...
- CCF-画字符-详细的注释
import java.io.BufferedReader; import java.io.IOException; import java.io.InputStream; import java.i ...