[知识点]网络流之Dinic算法

// 此博文为迁移而来,写于2014年2月6日,不代表本人现在的观点与看法。原始地址:http://blog.sina.com.cn/s/blog_6022c4720102vrg4.html

今天我们来谈谈网络流之Dinic算法。这种算法相比Edmond-Karp算法,更加快速,更加常用。还记得EK吗?每次为了防止流量堵塞,必须进行多次BFS/DFS,非常费时间。而Dinic大叔非常机智的发明了Dinic算法,让这个问题得以解决。

Dinic的核心内容是:反复进行BFS绘制出层次图,和DFS进行增广。所谓的层次图就是什么呢? 从源点到当前点的最近距离,可以存储到一个数组dep中。如图所示,这张图上,dep[1]=0,dep[2]=2,dep[3]=2,dep[4]=1。


       而层次图有什么用呢?1、在DFS增广时,当且仅当下一个点的层次是当前点的下一层才进入下一个点;2、是用来判断源点到汇点是否还有流量可以流。如果汇点已经不再层次图上了,说明没有多余的流量可以从源点流到汇点了,这个时候就可以结束搜索而输出答案了。

那么每进行完一次BFS,dep数组要清空。接下来的步骤就和EK算法一个意思了,但是正如江哥所说,这个是需要设置反向弧使流量可以顺利流走。找出当前增广路的最小流量,到汇点后将本增广路的所有子路减去该流量,且所有反向弧增加该流量。如图所示:

代码如下:

Code:

#include《cstdio》

#include《cstring》

#define MAXN 205

#define MAXM 205

#define INF 1<<30

struct edge

{

int v,next,flow;

};

int dep[MAXN],s,t,ans,h[MAXN],u,v,flow,m,n,tot;

edge list[MAXM];

int min(int a,int b)

{

return (a

}

void AddList(int u,int v,int flow)

{

tot++;

list[tot].next=h[u];

list[tot].v=v;

list[tot].flow=flow;

h[u]=tot;

}

void init()

{

freopen("EXMaxFlow.in","r",stdin);

freopen("EXMaxFlow.out","w",stdout);

scanf("%d %d",&m,&n);

for (int i=1;i<=m;i++)

{

scanf("%d %d %d",&u,&v,&flow);

AddList(u,v,flow);

AddList(v,u,0);

}

s=1; t=n;

}

int BFS()

{

int q[MAXN*MAXN],head,tail;

head=1; tail=2; q[1]=s; dep[s]=1;

while (head!=tail)

{

for (int x=h[q[head]];x!=0;x=list[x].next)

{

if (dep[list[x].v]==0 && list[x].flow>0)

{

dep[list[x].v]=dep[q[head]]+1;

q[tail++]=list[x].v;

}

}

head++;

}

if (dep[t]==0) return 0;

else return 1;

}

int DFS(int now,int RouteMinFlow)

{

int OldRouteMinFlow=0;

if (RouteMinFlow<=0 || now==t) return RouteMinFlow;

for (int x=h[now];x!=0;x=list[x].next)

{

if (dep[list[x].v]==dep[now]+1)

{

int temp=DFS(list[x].v,min(RouteMinFlow,list[x].flow));

list[x+1].flow+=temp;

list[x].flow-=temp;

RouteMinFlow-=temp;

OldRouteMinFlow+=temp;

if (RouteMinFlow==0) break;

}

}

return OldRouteMinFlow;

}

int main()

{

init();

while (BFS()==1) { ans+=DFS(s,INF); memset(dep,0,sizeof(dep)); }

printf("%d",ans);

}

时间: 2024-08-08 04:02:32

[知识点]网络流之Dinic算法的相关文章

[知识点]网络流之Edmond-Karp算法

// 此博文为迁移而来,写于2015年2月2日,不代表本人现在的观点与看法.原始地址:http://blog.sina.com.cn/s/blog_6022c4720102vr12.html 今天我们来讲一讲网络流.想当年的“网络流大神”的称号记忆犹新. 网络流,顾名思义,在网络上流.它的算法:Edmond-Karp算法,Dinic算法.首先我们来介绍一下Edmond-Karp算法,他的速度很慢,但是比较好理解,并且代码简单一些,一些大神都直接忽视掉这个老爷速度的算法了 = =. 网络流是什么呢

网络流最大流——dinic算法

前言 网络流问题是一个很深奥的问题,对应也有许多很优秀的算法.但是本文只会讲述dinic算法 最近写了好多网络流的题目,想想看还是写一篇来总结一下网络流和dinic算法以免以后自己忘了... 网络流问题简述 一个很普遍的例子就是--你家和自来水厂之间有许多中转站,中转站又由一些水管连接着.我们假设自来水厂的供水是无限的,并且中转站内能存储的水量也是无限的,但是管道有宽又窄,很显然管道内的流量必须小于等于管道的承载范围(否则管道就被撑爆了),那么问题就是要你求出你家最多能收到多大流量的水. emm

hiho一下 第115周:网络流一?Ford-Fulkerson算法 (Edmond-Karp,Dinic,SAP)

来看一道最大流模板水题,借这道题来学习一下最大流的几个算法. 分别用Edmond-Karp,Dinic ,SAP来实现最大流算法. 从运行结过来看明显SAP+当前弧优化+gap优化速度最快.   hiho一下 第115周:网络流一•Ford-Fulkerson算法 原题网址:http://hihocoder.com/contest/hiho115/problem/1 网络流一·Ford-Fulkerson算法 时间限制:10000ms 单点时限:1000ms 内存限制:256MB 描述 小Hi和

hiho一下 第119周 #1398 : 网络流五&#183;最大权闭合子图 【最小割-最大流--Ford-Fulkerson 与 Dinic 算法】

#1398 : 网络流五·最大权闭合子图 时间限制:10000ms 单点时限:1000ms 内存限制:256MB 描述 周末,小Hi和小Ho所在的班级决定举行一些班级建设活动. 根据周内的调查结果,小Hi和小Ho一共列出了N项不同的活动(编号1..N),第i项活动能够产生a[i]的活跃值. 班级一共有M名学生(编号1..M),邀请编号为i的同学来参加班级建设活动需要消耗b[i]的活跃值. 每项活动都需要某些学生在场才能够进行,若其中有任意一个学生没有被邀请,这项活动就没有办法进行. 班级建设的活

POJ 2135 Farm Tour (dinic算法,网络流)

构图方法: 注意题目中的边为无向边.新建源点s 和 汇点t 每两条道路连一条容量为1,费用为w的边.s到1连一条容量为1,费用为0 的边,n到 t 连一条容量为1,费用为0 的边,求最大流. #include <iostream> #include <cstring> #include <cstdlib> #include <cstdio> #include <algorithm> #include <queue> #include

hdu 3572 Task Schedule(网络流 dinic算法)

Task Schedule Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) Total Submission(s): 3412    Accepted Submission(s): 1197 Problem Description Our geometry princess XMM has stoped her study in computational geometry t

图论4——探索网络流的足迹:Dinic算法

1. 网络流:定义与简析 1.1 网络流是什么? 网络流是一种"类比水流的解决问题方法,与线性规划密切相关"(语出百度百科). 其实,在信息学竞赛中,简单的网络流并不需要太高深的数学知识. 首先我们需要知道一些名词是什么意思: 点(\(node\)).就是一个节点.点集通常用\(V\)表示.其中,有一个源点\(s\)和一个汇点\(t\),所有的流都从源点\(s\)出发,经过一些边之后到达汇点\(t\). 边(\(edge\)).这个东西和大家在其他图论知识中所用到的差不多,用于连接两个

zoj 3229 dinic算法的非递归实现以及有上下界的有源汇的网络流的最大流的求解

Shoot the Bullet Time Limit: 2 Seconds      Memory Limit: 32768 KB      Special Judge Gensokyo is a world which exists quietly beside ours, separated by a mystical border. It is a utopia where humans and other beings such as fairies, youkai(phantoms)

POJ 1273 Drainage Ditches(网络流dinic算法模板)

POJ 1273给出M条边,N个点,求源点1到汇点N的最大流量. 本文主要就是附上dinic的模板,供以后参考. #include <iostream> #include <stdio.h> #include <algorithm> #include <queue> #include <string.h> /* POJ 1273 dinic算法模板 边是有向的,而且存在重边,且这里重边不是取MAX,而是累加和 */ using namespace