poj 1273 hdu 1532 Drainage Ditches 最大流dinic 算法

来源:互联网 发布:淘宝一个钻要多少单 编辑:程序博客网 时间:2024/05/22 18:47
Problem 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 41 2 401 4 202 4 202 3 303 4 10
 

Sample Output
50
 

Source
USACO 93

题意:
每到下雨时农场主种的东西都会被淹没一部分,为了避免这种情况,他建立了一套排水系统。每条排水沟的起点都有调节阀门。求排水沟的最大流水速度。
题解:
就是裸最大流问题。我对最大流现在还是一知半解,掌握了一点皮毛而已。刚开始看的Ford-Fulkerson算法,感觉脑子不够用。在网上看了一段简单明了的代码感觉不错,不过没经过博主同意,没敢转载。这里有网址,有兴趣的可以去看下。
http://www.cnblogs.com/oa414/archive/2011/07/13/2105163.html
之后看了dinic算法,还是感觉脑子不够用……不过在看了大神的代码之后,自己有按照程序推了一遍,给代码加上了自己的见解,如有不足,敬请指正。
关于dinic算法的详解,在下小白一枚,就不献丑了,等以后完全掌握了最大流,再来发表个人理解。再奉上一位大神精彩讲解。
http://blog.csdn.net/u012914220/article/details/23865829
这位大神的博文中对在dinic算法中反向流量为何要相加,有独特易懂的解释。
我发这篇博客的原因是加深自己对dinic算法的理解,对代码的每一步都发表自己的见解,希望对和我一样的小白有所帮助。如有不足和错误,敬请指正,教导。
代码如下:
#include<stdio.h>#include<queue>#include<string.h>#include<algorithm>using namespace std;#define maxx 0x3f3f3f3fint mp[250][250];//建立邻接矩阵int dis[250];//到源点的距离,把图分层int q[2000];//队列int h,t;//首尾int n,m,maxflow;//点数边数,最大流int bfs()//搜索图中是否存在一条从源点到汇点的路,构建层次网络{    int i,s;    memset(dis,-1,sizeof(dis));//将dis数组初始化为-1    dis[1]=0;//到源点的距离为0    h=0;//头    t=1;//尾    q[1]=1;//入队    //从起点出发寻找一条可达到汇点的路    while(h<t)//当队列不为空    {        s=q[++h];        for(i=1; i<=n; i++)//遍历求出        {            if(dis[i]<0 && mp[s][i]>0)//求出            {                dis[i]=dis[s]+1;//相当于标记,表明此点已走过,存储点i到源点的距离,而非流量                q[++t]=i;            }        }    }    if(dis[n]>0)//能找到一条从源点到汇点的路,即已建好层次网络        return 1;    else        return 0;}//dfs代表一次增广,函数返回本次增广的流量,返回0表示无法增广int dfs(int x,int low){    int i,a=0;    if(x==n)//找到汇点返回增广的流量        return low;    for(i=1; i<=n; i++)    {        if(mp[x][i]<=0)//这条边连通            continue;        if(dis[i]!=dis[x]+1)//根据广搜得到的结果判断i是否为x的下一个点            continue;        a=dfs(i,min(low,mp[x][i]));//按照dis数组的值寻找bfs找到的路,沿着路的每一个点,取路中流量的最小值        if(a)//a不为0,代表能到汇点,能找到可增广路上的最小流量        {            mp[x][i]-=a;//在回溯的时候把经过的每一条边都减去最小流量            mp[i][x]+=a;//反向流量增加            return a;        }    }    return 0;}int main(){    int i,j,f,t,flow,tans;    while(~scanf("%d%d",&m,&n))    {        memset(mp,0,sizeof(mp));        for(i=1; i<=m; i++)        {            scanf("%d%d%d",&f,&t,&flow);            mp[f][t]+=flow;//可能有重边,注意是单向的        }        maxflow=0;        while(bfs())//一值把图分层,找到源点可到汇点的路        {            while(tans=dfs(1,maxx))//把每次搜到的路的最小流量相加                maxflow+=tans;        }        printf("%d\n",maxflow);    }}


阅读全文
0 0
原创粉丝点击