• 【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;
    }
    
  • 相关阅读:
    Flutter Android ERROR: ensureInitializationComplete must be called after startInitialization
    MySQL 创建用户表和好友表
    Android 广播的使用 文档使用的是 kotlin版本
    Flutter 分段器的使用
    Flutter 计算两个日期之间相差多少天,生成区间随机数
    Flutter 多环境
    Android ListView 的使用 Kotlin
    Android 自定义控件----基础
    Flutter 学习(3)------------通过List或者map循环数据渲染页面。。
    vs2015 编译报错:The project references NuGet package(s) that are missing on this computer...
  • 原文地址:https://www.cnblogs.com/AWCXV/p/7632086.html
Copyright © 2020-2023  润新知