您的位置:首页 > 大数据 > 人工智能

poj 1273 Drainage Ditches

2015-08-21 17:15 441 查看
click here ~~

[code]                               Drainage Ditches

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


题目大意:

现在有m个池塘(从1到m开始编号,1为源点,m为汇点),

及n条水渠,给出这n条水渠所连接的池塘和所能流过的水量,

求水渠中所能流过的水的最大容量.一道基础的最大流题目

解题思路:这是一个裸的最大流问题,就是套模板。。。。

具体我也是看大神的代码整的,这个模板还是不错的,都给出了详细的解释;

上代码:

[code]/*
Date : 2015-8-21下午

Author : ITAK

Motto :

今日的我要超越昨日的我,明日的我要胜过今日的我;
以创作出更好的代码为目标,不断地超越自己。
*/
#include <iostream>
#include <cstdio>

using namespace std;
///oo表示无穷大
const int oo = 1e9+5;
///mm表示边的最大数量,因为要双向建边
const int mm = 111111;
///点的最大数量
const int mn = 1000;
///node:节点数,src:源点,dest:汇点,edge:边数
int node, src, dest, edge;
///ver:边指向的结点,flow:边的流量,next:链表的下一条边
int ver[mm], flow[mm], next[mm];
///head:节点的链表头,work:用于算法中的临时链表头,dis:距离
int head[mn], work[mn], dis[mn], q[mn];

///初始化
void Init(int _node, int _src, int _dest)
{
    node = _node, src = _src, dest = _dest;
    for(int i=0; i<node; i++)
        head[i] = -1;
    edge = 0;
}

///增加边
void addedge(int u, int v, int c)
{
    ver[edge]=v,flow[edge]=c,next[edge]=head[u],head[u]=edge++;
    ver[edge]=u,flow[edge]=0,next[edge]=head[v],head[v]=edge++;
}

///广搜计算出每个点与源点的最短距离,如果不能到达汇点说明算法结束
bool Dinic_bfs()
{
    int i, u, v, l, r = 0;
    for(i=0; i<node; i++)
        dis[i] = -1;
    dis[q[r++]=src] = 0;
    for(l=0; l<r; l++)
        for(i=head[u=q[l]]; i>=0; i=next[i])
            if(flow[i] && dis[v=ver[i]]<0)
            {
                ///这条边必须有剩余流量
                dis[q[r++]=v] = dis[u] + 1;
                if(v == dest)
                    return 1;
            }
    return 0;
}

///寻找可行流的增广路算法,按节点的距离来找,加快速度
int Dinic_dfs(int u, int exp)
{
    if(u == dest)
        return exp;
    ///work 是临时链表头,这里用 i 引用它,这样寻找过的边不再寻找*
    for(int &i=work[u],v,tmp; i>=0; i=next[i])
    {
        if(flow[i]&&dis[v=ver[i]]==dis[u]+1&&(tmp=Dinic_dfs(v,min(exp,flow[i])))>0)
        {
            ///正反向边容量改变
            flow[i] -= tmp;
            flow[i^1] += tmp;
            return tmp;
        }
    }

    return 0;
}

///求最大流,直到没有可行流
int Dinic_flow()
{
    int i, ret=0, data;
    while(Dinic_bfs())
    {
        for(i=0; i<node; i++)
            work[i] = head[i];
        while(data = Dinic_dfs(src, oo))
            ret += data;//cout<<666<<endl;
    }

    return ret;
}
int main()
{
    ///套模板
    int m, n, u, v, c;
    while(~scanf("%d%d",&n,&m))
    {
        Init(m+1, 1, m);
        while(n--)
        {
            scanf("%d%d%d",&u,&v,&c);
            addedge(u, v, c);
        }
        printf("%d\n",Dinic_flow());
    }
    return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: