poj 1273 Drainage Ditches 網絡流最大流入門 ford-fulkerson

Drainage Ditches
Time Limit: 1000MS   Memory Limit: 10000K
Total Submissions: 70072   Accepted: 27200

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個池塘(從1到m開始編號,1爲源點,m爲匯點),及n條水渠,給出這n條水渠所連接的池塘和所能流過的水量,求水渠中所能流過的水的最大容量.一道基礎的最大流題目。

對於網絡流最大流ford-fulkerson算法,如何理解呢?

先考慮這樣的貪心算法:


但事實上有更優的路線如下:


貪心算法得到的結果是10,而上圖得到的結果是11。爲了找出二者的區別,不妨來看看它們的流量的差。


通過對流量的差的觀察我們發現,我們可以將原先得到的流給推回去,而得到新的流。因此,可以試着在之前的貪心算法加上這一操作,將算法做出如下改進。


下面是此題的代碼:

#include <cstdio>
#include <cstring>
#include <algorithm>
#include <vector>
#include <functional>
using namespace std;
const int INF = 0x3f3f3f3f;
const int MAXN = 2e2 + 10;
struct edge {
    int t, c, rev;
    edge(int _t, int _c, int _rev) {
        t = _t; c = _c; rev = _rev;
    }
};
int n, m;
vector<edge> G[MAXN];
bool vis[MAXN];

int dfs(int v, int t, int f) {
    if (v == t) return f;
    vis[v] = true;
    for (int i = 0; i < G[v].size(); ++i) {
        edge& e = G[v][i];
        if (!vis[e.t] && e.c > 0) {
            int d = dfs(e.t, t, min(f, e.c));
            if (d > 0) {
                e.c -= d;
                G[e.t][e.rev].c += d;
                return d;
            }
        }
    }
    return 0;
}

int max_flow(int s, int t) {
    int flow = 0;
    for (;;) {
        memset(vis, 0, sizeof(vis));
        int add = dfs(s, t, INF);
        if (add == 0) return flow;
        flow += add;
    }
}

int main() {
#ifdef NIGHT_13
    freopen("in.txt", "r", stdin);
#endif
    while (scanf("%d%d", &n, &m) != EOF) {
        for (int i = 0; i <= m; ++i) {
            G[i].clear();
        }
        for (int i = 0, v, t, c; i < n; ++i) {
            scanf("%d%d%d", &v, &t, &c);
            G[v].push_back(edge(t, c, G[t].size()));
            G[t].push_back(edge(v, 0, G[v].size() - 1));
        }
        printf("%d\n", max_flow(1, m));
    }
    return 0;
}

參考資料:《挑戰程序設計競賽》巫澤俊譯
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章