Dinic 算法模板 

Dinic算法是一种比較easy实现的。相对照较快的最大流算法。

求最大流的本质,就是不停的寻找增广路径。直到找不到增广路径为止。

对于这个一般性的过程,Dinic算法的优化例如以下:





(1)Dinic算法首先对图进行一次BFS,然后在BFS生成的层次图中进行多次DFS。

层次图的意思就是,仅仅有在BFS树中深度相差1的节点才是连接的。

这就切断了原有的图中的很多不必要的连接。非常牛逼!

这是须要证明的,预计证明也非常复杂。

(2)除此之外,每次DFS完后,会找到路径中容量最小的一条边。

在这条边之前的路径的容量是大于等于这条边的容量的。

那么从这条边之前的点。可能引发出别的增广路径。

比方说 S -> b -> c -> d -> T 是一条增广路径。容量最小的边是 b -> c。

可能存在一条 S -> b -> e -> f -> g -> T 这种增广路径。

这种话,在找到第一条增广路径后,仅仅须要回溯到 b 点,就能够继续找下去了。

这样做的优点是。避免了找到一条路径就从头開始寻找另外一条的开销。

也就是再次从 S 寻找到 b 的开销。

这个过程看似复杂。可是代码实现起来非常优雅,由于它的本质就是回溯!

(3)在同一次 DFS 中。假设从一个点引发不出不论什么的增广路径。就将这个点在层次图中抹去。

Description

Every time it rains on Farmer John's fields, a pond forms over Bessie's favorite clover patch. This means that the clover is covered by water for awhile and takes quite a long time to regrow. Thus, Farmer John has built a set of drainage ditches so that Bessie's
clover patch is never covered in water. Instead, the water is drained to a nearby stream. Being an ace engineer, Farmer John has also installed regulators at the beginning of each ditch, so he can control at what rate water flows into that ditch. 

Farmer John knows not only how many gallons of water each ditch can transport per minute but also the exact layout of the ditches, which feed out of the pond and into each other and stream in a potentially complex network. 

Given all this information, determine the maximum rate at which water can be transported out of the pond and into the stream. For any given ditch, water flows in only one direction, but there might be a way that water can flow in a circle. 

Input

The input includes several cases. For each case, the first line contains two space-separated integers, N (0 <= N <= 200) and M (2 <= M <= 200). N is the number of ditches that Farmer John has dug. M is the number of intersections points
for those ditches. Intersection 1 is the pond. Intersection point M is the stream. Each of the following N lines contains three integers, Si, Ei, and Ci. Si and Ei (1 <= Si, Ei <= M) designate the intersections between which this ditch flows. Water will flow
through this ditch from Si to Ei. Ci (0 <= Ci <= 10,000,000) is the maximum rate at which water will flow through the ditch.

Output

For each case, output a single integer, the maximum rate at which water may emptied from the pond.

Sample Input

5 4
1 2 40
1 4 20
2 4 20
2 3 30
3 4 10

Sample Output

50
</pre><pre name="code" class="cpp">#include"stdio.h"
#include"string.h"
#define N 605
#define min(a,b) (a<b? a:b)
const int inf=0x7fffffff;
struct node
{
int u,v,w,next;
}map[N*4];
int t,head[N],q[N],dis[N];
void add(int u,int v,int w)
{
map[t].u=u;
map[t].v=v;
map[t].w=w;
map[t].next=head[u];
head[u]=t++;
}
int bfs(int s,int t)
{
int i,x,v,l,r;
memset(dis,0,sizeof(dis)); //节点的高度标号
dis[s]=1;
l=r=0; //队列两端
q[r++]=s; //模拟队列
while(l<r)
{
x=q[l++];
for(i=head[x];i!=-1;i=map[i].next)
{
v=map[i].v;
if(map[i].w&&!dis[v])
{
dis[v]=dis[x]+1;
if(v==t)
return 1;
q[r++]=v;
}
}
}
return 0;
}
int dfs(int s,int t,int lim)
{
int i,v,tmp,cost=0;
if(s==t)
return lim;
for(i=head[s];i!=-1;i=map[i].next) //枚举该点连通的全部边
{
v=map[i].v;
if(map[i].w&&dis[s]==dis[v]-1)
{
tmp=dfs(v,t,min(lim-cost,map[i].w));
if(tmp>0)
{
map[i].w-=tmp; //利用反向边的奇偶性。添加反向边的流量
map[i^1].w+=tmp;
cost+=tmp;
if(lim==cost)
break;
}
else //在同一次 DFS 中。 假设从一个点引发不出不论什么的增广路径,就将这个点在层次图中抹去。
dis[v]=-1;
}
}
return cost;
}
void dinic(int s,int t)
{
int ans=0;
while(bfs(s,t))
ans+=dfs(s,t,inf);
printf("%d\n",ans);
}
int main()
{
int u,v,w,n,m;
while(~scanf("%d%d",&m,&n))
{
t=0;
memset(head,-1,sizeof(head));
while(m--)
{
scanf("%d%d%d",&u,&v,&w);
add(u,v,w);
add(v,u,0); //建边,反向边流量为零
}
dinic(1,n);
}
return 0;
}

dinic算法学习(以poj1273为例)的更多相关文章

  1. Dinic算法学习

    转自 此文虽为转载,但博主的网络流就是从这开始的,认为写的不错 网络流基本概念 什么是网络流 在一个有向图上选择一个源点,一个汇点,每一条边上都有一个流量上限(以下称为容量),即经过这条边的流量不能超 ...

  2. 最大流EK算法/DINIC算法学习

    之前一直觉得很难,没学过网络流,毕竟是基础知识现在重新来看. 定义一下网络流问题,就是在一幅有向图中,每条边有两个属性,一个是cap表示容量,一个是flow 表示流过的流量.我们要求解的问题就是从S点 ...

  3. Dinic算法学习&&HDU2063

    http://www.cnblogs.com/SYCstudio/p/7260613.html 看这篇博文懂了一点,做题再体会体会吧 找了好久都没找到一个好用的模板…… 我也是佛了..最后决定用峰神的 ...

  4. 【最大流之Dinic算法】POJ1273 【 & 当前弧优化 & 】

    总评一句:Dinic算法的基本思想比较好理解,就是它的当前弧优化的思想,网上的资料也不多,所以对于当前弧的优化,我还是费了很大的功夫的,现在也一知半解,索性就写一篇博客,来发现自己哪里的算法思想还没理 ...

  5. 学习笔记 --- 最大流Dinic算法

    为与机房各位神犇同步,学习下网络流,百度一下发现竟然那么多做法,最后在两种算法中抉择,分别是Dinic和ISAP算法,问过 CA爷后得知其实效率上无异,所以决定跟随Charge的步伐学习Dinic,所 ...

  6. POJ1273:Drainage Ditches(最大流入门 EK,dinic算法)

    http://poj.org/problem?id=1273 Description Every time it rains on Farmer John's fields, a pond forms ...

  7. dinic算法求最大流的学习

    http://trp.jlu.edu.cn/software/net/lssx/4/4.38.htm http://www.cnblogs.com/zen_chou/archive/0001/01/0 ...

  8. Power Network(网络流最大流 & dinic算法 + 优化)

    Power Network Time Limit: 2000MS   Memory Limit: 32768K Total Submissions: 24019   Accepted: 12540 D ...

  9. 算法学习之C语言基础

    算法学习,先熟悉一下C语言哈!!! #include <conio.h> #include<stdio.h> int main(){ printf(+); getch(); ; ...

随机推荐

  1. HDU 4007 Dave(离散化)

    Dave Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65768/65768 K (Java/Others)Total Submis ...

  2. nodejs学习(三)--express连接mysql数据库,mysql查询封装

    一.说一下 连接不同的数据库需要安装相应的插件,此demo使用mysql数据库,需自行安装mysql数据库软件. 新建数据库webapp, 新建表users: 二.直接开码 npm install m ...

  3. 今日SGU 5.3

    SGU 107 题意:输入一个N,表示N位数字里面有多少个的平方数的结尾9位是987654321 收获:打表,你发现相同位数的数相乘结果的最后几位,就和那两个相乘的数最后几位相乘一样,比如3416*8 ...

  4. 洛谷 P1957 口算练习题

    洛谷 P1957 口算练习题 题目描述 王老师正在教简单算术运算.细心的王老师收集了i道学生经常做错的口算题,并且想整理编写成一份练习. 编排这些题目是一件繁琐的事情,为此他想用计算机程序来提高工作效 ...

  5. WPF动画基础及实例

    1.介绍 在之前做winform中, 也做过一些动画效果, 但是整个动画都需要我们自己去编写, 利用计时器或线程去直接操作UI元素的属性, 然而在WPF中, 则是通过一种全新的基于属性的动画系统, 改 ...

  6. 非阻塞键盘检测getchar()

    #include <stdio.h> #include <conio.h> #include <Windows.h> int main() { char c; wh ...

  7. 1.18 Python基础知识 - Python内置函数

    官方地址:https://docs.python.org/3.5/library/functions.html abs(x): 返回数字的绝对值 all(iterable): 如果迭代器的所有元素都为 ...

  8. 用Bandwidth Controller实现局域网带宽控制

    用Bandwidth Controller实现局域网带宽控制 很多做网络管理的朋友都知晓微软的ISA Serve防火墙,在ISA Server 2000中,带宽管理功能是通过设置优先级来实现,但是管理 ...

  9. javafx spring

    javafx spring http://files.cnblogs.com/files/rojas/airhacks_control.zip

  10. 用vue.js的v-for,v-if,computed写一个分页样式

    在学Vue,总想写个分页,先写了一个样式. 主要看思路: 思路简单,得到总页数,判断总页数,循环. 先判断总页数是否需要分页,总页数==1页就不分了. 再判断总页数<11就不用--. 总页数&g ...