zoukankan      html  css  js  c++  java
  • 【47.63%】【hdu 1532】Drainage Ditches

    Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)
    Total Submission(s): 15777 Accepted Submission(s): 7514

    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 4
    1 2 40
    1 4 20
    2 4 20
    2 3 30
    3 4 10

    Sample Output
    50

    【题目链接】:http://acm.hdu.edu.cn/showproblem.php?pid=1532

    【题解】

    让你找从点1到点m的最大流;
    用那个E-K算法搞增广路做就好;
    用广搜来搞;
    路上的边权是剩余网络的边权;
    每次修改a后;
    正向边+a;
    反向边-a;
    一开始输入的z是这个网络上边的容量限制(一开始没有任何流);
    所以每次修改a后就直接增加答案a;
    中途跳出队列可能dl不为空,所以要清空队列;
    如果还能找到增广路就继续找;继续增加最大流;

    【完整代码】

    #include <cstdio>
    #include <cstdlib>
    #include <cmath>
    #include <set>
    #include <map>
    #include <iostream>
    #include <algorithm>
    #include <cstring>
    #include <queue>
    #include <vector>
    #include <stack>
    #include <string>
    #define lson l,m,rt<<1
    #define rson m+1,r,rt<<1|1
    #define LL long long
    
    using namespace std;
    
    const int MAXN = 300;
    const int INF = 2100000000;
    const int dx[5] = {0,1,-1,0,0};
    const int dy[5] = {0,0,0,-1,1};
    const double pi = acos(-1.0);
    
    int n,m;
    int pre[MAXN];
    int flow[MAXN][MAXN];
    bool mark[MAXN];
    vector <int> a[MAXN];
    queue <int>dl;
    
    void read2(LL &r)
    {
        r = 0;
        char t = getchar();
        while (!isdigit(t) && t!='-') t = getchar();
        LL sign = 1;
        if (t == '-')sign = -1;
        while (!isdigit(t)) t = getchar();
        while (isdigit(t)) r = r * 10 + t - '0', t = getchar();
        r = r*sign;
    }
    
    void read1(int &r)
    {
        r = 0;
        char t = getchar();
        while (!isdigit(t)&&t!='-') t = getchar();
        int sign = 1;
        if (t == '-')sign = -1;
        while (!isdigit(t)) t = getchar();
        while (isdigit(t)) r = r * 10 + t - '0', t = getchar();
        r = r*sign;
    }
    
    
    int main()
    {
        //freopen("F:\rush.txt","r",stdin);
        while (~scanf("%d%d",&n,&m))
        {
            memset(flow,0,sizeof(flow));
            for (int i = 1;i <= n;i++)
            {
                int x,y,z;
                read1(x);read1(y);read1(z);
                flow[x][y]+=z;
            }
            int f = 0;
            while (true)
            {
                memset(mark,false,sizeof(mark));
                memset(pre,0,sizeof(pre));
                while (!dl.empty())
                    dl.pop();
                dl.push(1);
                mark[1] = true;
                while (!dl.empty())
                {
                    int x = dl.front();
                    dl.pop();
                    if (x==m)
                        break;
                    for (int i = 1;i <= m;i++)
                        if (flow[x][i]>0 && !mark[i])
                        {
                            mark[i] = true;
                            pre[i] = x;
                            dl.push(i);
                        }
                }
                if (!mark[m])
                    break;
                int mi = INF;
                int i = m;
                while (i!=1)
                {
                    mi = min(mi,flow[pre[i]][i]);
                    i = pre[i];
                }
                if (mi==INF)
                    break;
                i = m;
                while (i!=1)
                {
                    flow[pre[i]][i]-=mi;
                    flow[i][pre[i]]+=mi;
                    i = pre[i];
                }
                f+=mi;
            }
            cout << f<<endl;
        }
        return 0;
    }
    
  • 相关阅读:
    活用 %取余 用于变量循环
    jquery滚动条固定在某一位置
    jquary中各种相似操作介绍
    jquary中滚动条滚动到底部
    JSON到字符串之间的解析
    ecshop删去版权等信息
    分享代码和网页地图
    ecshop版权的修改,头部,底部
    ECSHOP中transport.js和jquery的冲突的简单解决办法
    从Eclipse迁移到Android Studio碰到的问题记录
  • 原文地址:https://www.cnblogs.com/AWCXV/p/7632086.html
Copyright © 2011-2022 走看看