POJ 1273-Drainage Ditches(最大流-Edmond-Karp演算法/模板)

kewlgrl發表於2016-07-27

Drainage Ditches

Time Limit: 1000MS   Memory Limit: 10000K
Total Submissions: 69007   Accepted: 26729

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

Source


題目意思:

m個池塘,池塘1m開始編號,其中1為源點,m為匯點n條水渠給出這n條水渠所連線的池塘和所能流過的水量求水渠中所能流過的水的最大容量。

解題思路:

最大流問題,直接上Edmond-Karp演算法/模板。

傳送門:

演算法什麼的講得很好很詳細

#include<iostream>
#include<cstdio>
#include<cstring>
#include<vector>
#include<queue>
#include<algorithm>
#include <queue>
using namespace std;

#define MAXN 201
int maxData = 0x7fffffff;
int capacity[MAXN][MAXN]; //記錄殘留網路的容量
int flow[MAXN];                //標記從源點到當前節點實際還剩多少流量可用
int pre[MAXN];                 //標記在這條路徑上當前節點的前驅,同時標記該節點是否在佇列中
int n,m;
queue<int> myqueue;
int BFS(int src,int des)
{
    int i,j;
    while(!myqueue.empty())       //佇列清空
        myqueue.pop();
    for(i=1; i<m+1; ++i)
    {
        pre[i]=-1;
    }
    pre[src]=0;
    flow[src]= maxData;
    myqueue.push(src);
    while(!myqueue.empty())
    {
        int index = myqueue.front();
        myqueue.pop();
        if(index == des)            //找到了增廣路徑
            break;
        for(i=1; i<m+1; ++i)
        {
            if(i!=src && capacity[index][i]>0 && pre[i]==-1)
            {
                pre[i] = index; //記錄前驅
                flow[i] = min(capacity[index][i],flow[index]);   //關鍵:迭代的找到增量
                myqueue.push(i);
            }
        }
    }
    if(pre[des]==-1)      //殘留圖中不再存在增廣路徑
        return -1;
    else
        return flow[des];
}
int maxFlow(int src,int des)
{
    int increasement= 0;
    int sumflow = 0;
    while((increasement=BFS(src,des))!=-1)
    {
        int k = des;          //利用前驅尋找路徑
        while(k!=src)
        {
            int last = pre[k];
            capacity[last][k] -= increasement; //改變正向邊的容量
            capacity[k][last] += increasement; //改變反向邊的容量
            k = last;
        }
        sumflow += increasement;
    }
    return sumflow;
}
int main()
{
    ios::sync_with_stdio(false);
    cin.tie(0);
    int i,j;
    int start,end,ci;
    while(cin>>n>>m)
    {
        memset(capacity,0,sizeof(capacity));
        memset(flow,0,sizeof(flow));
        for(i=0; i<n; ++i)
        {
            cin>>start>>end>>ci;
            if(start == end)               //考慮起點終點相同的情況
                continue;
            capacity[start][end] +=ci;     //此處注意可能出現多條同一起點終點的情況
        }
        cout<<maxFlow(1,m)<<endl;
    }
    return 0;
}


相關文章