POJ 1273 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条渠道,n个渠道可以到达的点,以及每条渠道所能运输水的最大流量,同一条渠道可能有不同的流量,第1个点为水的源点,第n个点为水的汇点,现在问从源点到汇点的最低流量是多少。

1.Edmonds-Karp 最短增广路算法:
#include<stdio.h>
#include<queue>
#include<string.h>
#include<algorithm>
#define INF 0x3f3f3f3f
#define N 210
using namespace std;

int G[N][N], f[N];
int n;

int BFS(int Start, int End) //查找能否从源点到达汇点
{
    int i, u;

    memset(f, 0, sizeof(f)); //f数组保存一条渠道的始点

    queue<int>Q;
    Q.push(Start);

    while (!Q.empty())
    {
        u = Q.front(); Q.pop();

        if (u == End) return 1;

        for (i = 1; i <= n; i++)
        {
            if (G[u][i] && !f[i]) //如果该渠道还有流量,且还未遍历该点
            {
                Q.push(i);
                f[i] = u; //让其父节点为该渠道的始点,便于添加反边
            }
        }
    }

    return 0;
}

int EK(int Start, int End)
{
    int Max = 0, Min, i;

    while (BFS(Start, End)) //一直查找到不能到达汇点
    {
        Min = INF;

        for (i = End; i != Start; i = f[i])
            Min = min(Min, G[f[i]][i]); //计算每一次的路径所能达到的最大流量(取决于每段路径流量最少的那个)
        for (i = End; i != Start; i = f[i])
        {
            G[f[i]][i] -= Min;
            G[i][f[i]] += Min; //添加反边
        } 

        Max += Min;
    }

    return Max; //保存流到汇点的最大流量
}

int main ()
{
    int m, a, b, c, ans;

    while (scanf("%d%d", &m, &n) != EOF)
    {
        memset(G, 0, sizeof(G));

        while (m--)
        {
            scanf("%d%d%d", &a, &b, &c);
            G[a][b] += c; //可能存在重复渠道的情况,需要将最大流量加起来,这样才能保证流到汇点的流量最大
        }

        ans = EK(1, n);

        printf("%d\n", ans);
    }

    return 0;
}

2.Dinic 快速网络流算法:

#include<stdio.h>
#include<queue>
#include<string.h>
#include<algorithm>
using namespace std;

const int INF=0x3f3f3f3f;
const int N=210;

int G[N][N], layer[N], n; //layer数组保存的是该点在进行BFS搜索时在第几层

int BFS(int Start, int End)
{
    int i, u;

    memset(layer, -1, sizeof(layer)); //每次查询时都重新构图了,所以每次都需要初始化

    queue<int>Q;
    Q.push(Start);
    layer[Start] = 1; //让源点为第一层

    while (!Q.empty())
    {
        u = Q.front(); Q.pop();

        if (u == n) return 1; //此时已经达到汇点,可以不用再继续查找

        for (i = 1; i <= n; i++)
        {
            if (layer[i] == -1 && G[u][i]) //要是该点还未遍历且有最大流量,此时该点层数+1
            {
                layer[i] = layer[u]+1;
                Q.push(i);
            }
        }
    }

    return 0;
}

int DFS(int u, int mini)
{
    int i, ans;

    if (u == n) return mini; //如果该点为汇点,说明这条路径的最小值已经找到

    for (i = 1; i <= n; i++)
    {
        if (G[u][i] && layer[i] == layer[u]+1 && (ans = DFS(i, min(mini, G[u][i])))) //ans的值肯定不会是0,是最终这条路径上的最小值
        {
            G[u][i] -= ans;                                                          //因为ans=0时说明该点不能达到汇点,回溯到for循坏,只有能达到汇点才能回溯到这里,而此时ans就是最小值
            G[i][u] += ans; //增加反边

            return ans;
        }
    }

    return 0;
}

int Dinic(int Start, int End)
{
    int ans = 0, num;

    while (BFS(Start, End)) //一直到不能达到汇点为止
    {
        while (1)
        {
            num = DFS(1, INF);

            if (num == 0) break; //等于0说明不能到达汇点

            ans += num; //将每次重新构图后的最小值相加
        }
    }

    return ans; //得到最大流量
}

int main ()
{
    int m, a, b, c, ans;

    while (scanf("%d%d", &m, &n) != EOF)
    {
        memset(G, 0, sizeof(G));

        while (m--)
        {
            scanf("%d%d%d", &a, &b, &c);
            G[a][b] += c; //防止有重边
        }

        ans = Dinic(1, n);

        printf("%d\n", ans);
    }

    return 0;
}
时间: 2024-10-12 13:27:46

POJ 1273 Drainage Ditches(网络流模板)的相关文章

POJ 1273 Drainage Ditches(网络流 最大流)

Drainage Ditches Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 55893   Accepted: 21449 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

POJ 1273 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

POJ 1273 Drainage Ditches (网络流Dinic模板)

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

POJ 1273 Drainage Ditches (网络流最大流基础 Edmonds_Karp算法)

Drainage Ditches Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 59219   Accepted: 22740 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

poj 1273 Drainage Ditches 网络流最大流基础

Drainage Ditches Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 59176   Accepted: 22723 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

NYOJ 323 &amp;&amp; HDU 1532 &amp;&amp; POJ 1273 Drainage Ditches (网络流之最大流入门)

链接:click here 题意:给出n个河流,m个点,以及每个河流的流量,求从1到m点的最大流量. 思路:最裸的网络流题目  意思就是求从源点到汇点的最大流. 第一道网络流,一边看着书上的介绍,一边敲下代码: 用的是网络流算法ford-fulkerson 题目数据量小,邻接表和邻接矩阵都可以过 代码: #include <ctype.h> //最大流 入门 #include <stdio.h> #include <vector> #include <stdlib

POJ 1273 Drainage Ditches(初识网络流)

开始研究网络流了,看了两个晚上吧,今天总算动手实践一下,有了更深的理解 总结一下:在最大流中,容量与实际流量满足3点: 1.实际流量<=容量 2.任意两点之间   : 流量(a->b)==流量(b->a) 3.流量守恒原则   :从s流出的流量 == t流入的流量 一.为什么叫增广路,因为在所有的流量网络中,会存在一个残量,所以在整个残量网络中,找到一个最小值,加到所有的流量线路里,便叫增广. 二.为什么要修改反向流量,因为在更新流量网时,当前选择的并不一定就是最优解,比如u->v

POJ 1273 Drainage Ditches(我的EK算法模板)

题意:给你n条边,目标位置t:接下来是每条边,包括起点,终点,容量: 感想:第一道最大流的代码,这道题是我更深地理解了Ek算法,不过这道题有个超坑的情况,那就是出现重边的情况==! 思路:EK算法 AC代码: #include<stdio.h> #include<string.h> #include<algorithm> #include<queue> using namespace std; #define INF 100000000 #define N

POJ 1273 Drainage Ditches (网络最大流)

http://poj.org/problem?id=1273 Drainage Ditches Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 55235   Accepted: 21104 Description Every time it rains on Farmer John's fields, a pond forms over Bessie's favorite clover patch. This means

POJ 1273 Drainage Ditches 最大流

很裸的最大流问题,不过注意会有重边,o(╯□╰)o,被阴了WA了一发 还有就是要用long long #include <cstdio> #include <cstring> #include <cmath> #include <algorithm> #include <climits> #include <string> #include <iostream> #include <map> #include