dinic算法学习(以poj1273为例)
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
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
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
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为例)的更多相关文章
- Dinic算法学习
转自 此文虽为转载,但博主的网络流就是从这开始的,认为写的不错 网络流基本概念 什么是网络流 在一个有向图上选择一个源点,一个汇点,每一条边上都有一个流量上限(以下称为容量),即经过这条边的流量不能超 ...
- 最大流EK算法/DINIC算法学习
之前一直觉得很难,没学过网络流,毕竟是基础知识现在重新来看. 定义一下网络流问题,就是在一幅有向图中,每条边有两个属性,一个是cap表示容量,一个是flow 表示流过的流量.我们要求解的问题就是从S点 ...
- Dinic算法学习&&HDU2063
http://www.cnblogs.com/SYCstudio/p/7260613.html 看这篇博文懂了一点,做题再体会体会吧 找了好久都没找到一个好用的模板…… 我也是佛了..最后决定用峰神的 ...
- 【最大流之Dinic算法】POJ1273 【 & 当前弧优化 & 】
总评一句:Dinic算法的基本思想比较好理解,就是它的当前弧优化的思想,网上的资料也不多,所以对于当前弧的优化,我还是费了很大的功夫的,现在也一知半解,索性就写一篇博客,来发现自己哪里的算法思想还没理 ...
- 学习笔记 --- 最大流Dinic算法
为与机房各位神犇同步,学习下网络流,百度一下发现竟然那么多做法,最后在两种算法中抉择,分别是Dinic和ISAP算法,问过 CA爷后得知其实效率上无异,所以决定跟随Charge的步伐学习Dinic,所 ...
- POJ1273:Drainage Ditches(最大流入门 EK,dinic算法)
http://poj.org/problem?id=1273 Description Every time it rains on Farmer John's fields, a pond forms ...
- dinic算法求最大流的学习
http://trp.jlu.edu.cn/software/net/lssx/4/4.38.htm http://www.cnblogs.com/zen_chou/archive/0001/01/0 ...
- Power Network(网络流最大流 & dinic算法 + 优化)
Power Network Time Limit: 2000MS Memory Limit: 32768K Total Submissions: 24019 Accepted: 12540 D ...
- 算法学习之C语言基础
算法学习,先熟悉一下C语言哈!!! #include <conio.h> #include<stdio.h> int main(){ printf(+); getch(); ; ...
随机推荐
- 验证list的底层数据结构
<STL源代码剖析>中,指出SGI STL的list底层数据结构式循环双向链表.而且在链表尾端留一个空白节点.让end指向它.因为是双向的,那么list的迭代器必须是Bidirection ...
- Token ,Cookie和Session的区别--学习笔记
http://blog.csdn.net/tobetheender/article/details/52485948 Token token的意思是“令牌”,是用户身份的验证方式,最简单的token组 ...
- 搭建 Docker 环境
- 韦东山ARM裸机笔记(1)
1.一个嵌入式Linux系统的软件组成:单片机大全Bootloader-->Linux驱动-->Linux APP-->Linux GUI(Android/QT) 2.驱动程序=软件 ...
- col---过滤控制字符
- 项目报错:Cannot find class file for javax/servlet/ServletException
两种解决方法: 1. 假设是Maven项目,加入servlet-api依赖包: <dependency> <groupId>javax.servlet</groupId& ...
- DOM和SAX是应用中操纵XML文档的差别
查看原文:http://www.ibloger.net/article/205.html DOM和SAX是应用中操纵XML文档的两种主要API.它们分别解释例如以下: DOM.即Do ...
- 简单的WINFORM窗口,体验WINFORM带来的快感
当习惯成为一种自然,就不再喜欢那种条条框框的规则 using System; using System.Windows.Forms; namespace Window{ class Window{ s ...
- HTML5的设计目的是为了在移动设备上支持多媒体
HTML5的设计目的是为了在移动设备上支持多媒体
- Java 大数
How Many Fibs? Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)To ...