HDU 1532 Drainage Ditches (网络流)

A - Drainage Ditches

Time Limit:1000MS     Memory Limit:32768KB     64bit IO Format:%I64d & %I64u

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

题意: 给一个有向有环图,给出每条边到容量上限,无下限,源点是1,汇点是n,求最大流。赤裸裸点网络流,我用的ISAP算法。第一次过点网络流^_^

思路: ISAP模板过。白书上没给ISAP的BFS。。搞了好久才知道怎么改。。

代码

#include <vector>
#include <cstdio>
#include <cstring>
#include <queue>
#define FOR(i,n) for(i=1;i<=(n);i++)
using namespace std;
const int INF = 2e9+10;
const int N = 210;

struct Edge{
    int from,to,cap,flow;
};

struct ISAP{
    int n,m,s,t;
    int p[N],num[N];
    vector<Edge> edges;
    vector<int> G[N];
    bool vis[N];
    int d[N],cur[N];
    void init(int _n,int _m)
    {
        n=_n; m=_m;
        int i;
        edges.clear();
        FOR(i,n)
        {
            G[i].clear();
            d[i]=INF;
        }
    }
    void AddEdge(int from,int to,int cap)
    {
        edges.push_back((Edge){from,to,cap,0});
        edges.push_back((Edge){to,from,0,0});
        m = edges.size();
        G[from].push_back(m-2);
        G[to].push_back(m-1);
    }
    bool BFS()
    {
        memset(vis,0,sizeof(vis));
        queue<int> Q;
        Q.push(t);
        d[t]=0;
        vis[t]=1;
        while(!Q.empty())
        {
            int x = Q.front(); Q.pop();
            for(unsigned i=0;i<G[x].size();i++)
            {
                Edge& e = edges[G[x][i]^1];
                if(!vis[e.from] && e.cap>e.flow)
                {
                    vis[e.from]=1;
                    d[e.from] = d[x]+1;
                    Q.push(e.from);
                }
            }
        }
        return vis[s];
    }
    int Augment()
    {
        int x=t, a=INF;
        while(x!=s)
        {
            Edge& e = edges[p[x]];
            a = min(a,e.cap-e.flow);
            x = edges[p[x]].from;
        }
        x = t;
        while(x!=s)
        {
            edges[p[x]].flow+=a;
            edges[p[x]^1].flow-=a;
            x=edges[p[x]].from;
        }
        return a;
    }
    int Maxflow(int _s,int _t)
    {
        s=_s; t=_t;
        int flow = 0, i;
        BFS();
//        FOR(i,n) printf("%d ",d[i]); puts("");
        if(d[s]>=n) return 0;
        memset(num,0,sizeof(num));
        memset(p,0,sizeof(p));
        FOR(i,n) num[d[i]]++;
        int x=s;
        memset(cur,0,sizeof(cur));
        while(d[s]<n)
        {
            if(x==t)
            {
                flow+=Augment();
                x=s;
            }
            int ok=0;
            for(unsigned i=cur[x];i<G[x].size();i++)
            {
                Edge& e=edges[G[x][i]];
                if(e.cap>e.flow && d[x]==d[e.to]+1)
                {
                    ok=1;
                    p[e.to]=G[x][i];
                    cur[x]=i;
                    x=e.to;
                    break;
                }
            }
            if(!ok)
            {
                int m=n-1;
                for(unsigned i=0;i<G[x].size();i++)
                {
                    Edge& e=edges[G[x][i]];
                    if(e.cap>e.flow) m=min(m,d[e.to]);
                }
                if(--num[d[x]]==0) break;
                num[d[x]=m+1]++;
                cur[x]=0;
                if(x!=s) x=edges[p[x]].from;
            }
        }
        return flow;
    }
};

ISAP isap;

int main()
{
    freopen("in","r",stdin);
    int n,m,u,v,c;
    while(scanf("%d%d",&m,&n)!=EOF)
    {
        isap.init(n,m);
        while(m--)
        {
            scanf("%d%d%d",&u,&v,&c);
            isap.AddEdge(u,v,c);
            //isap.AddEdge(v,u,c);
        }
        printf("%d\n",isap.Maxflow(1,n));
    }
    return 0;
}

ISAP 模板

注意用宏定义的FOR来做点的初始化,有些题目点所从0开始编号有些所从1开始,所以需要用一个宏定义

struct Edge{
    int from,to,cap,flow;
};

struct ISAP{
    int n,m,s,t;
    int p[N],num[N];
    vector<Edge> edges;
    vector<int> G[N];
    bool vis[N];
    int d[N],cur[N];
    void init(int _n,int _m)
    {
        n=_n; m=_m;
        int i;
        edges.clear();
        FOR(i,n)
        {
            G[i].clear();
            d[i]=INF;
        }
    }
    void AddEdge(int from,int to,int cap)
    {
        edges.push_back((Edge){from,to,cap,0});
        edges.push_back((Edge){to,from,0,0});
        m = edges.size();
        G[from].push_back(m-2);
        G[to].push_back(m-1);
    }
    bool BFS()
    {
        memset(vis,0,sizeof(vis));
        queue<int> Q;
        Q.push(t);
        d[t]=0;
        vis[t]=1;
        while(!Q.empty())
        {
            int x = Q.front(); Q.pop();
            for(unsigned i=0;i<G[x].size();i++)
            {
                Edge& e = edges[G[x][i]^1];
                if(!vis[e.from] && e.cap>e.flow)
                {
                    vis[e.from]=1;
                    d[e.from] = d[x]+1;
                    Q.push(e.from);
                }
            }
        }
        return vis[s];
    }
    int Augment()
    {
        int x=t, a=INF;
        while(x!=s)
        {
            Edge& e = edges[p[x]];
            a = min(a,e.cap-e.flow);
            x = edges[p[x]].from;
        }
        x = t;
        while(x!=s)
        {
            edges[p[x]].flow+=a;
            edges[p[x]^1].flow-=a;
            x=edges[p[x]].from;
        }
        return a;
    }
    int Maxflow(int _s,int _t)
    {
        s=_s; t=_t;
        int flow = 0, i;
        BFS();
        if(d[s]>=n) return 0;
        memset(num,0,sizeof(num));
        memset(p,0,sizeof(p));
        FOR(i,n) num[d[i]]++;
        int x=s;
        memset(cur,0,sizeof(cur));
        while(d[s]<n)
        {
            if(x==t)
            {
                flow+=Augment();
                x=s;
            }
            int ok=0;
            for(unsigned i=cur[x];i<G[x].size();i++)
            {
                Edge& e=edges[G[x][i]];
                if(e.cap>e.flow && d[x]==d[e.to]+1)
                {
                    ok=1;
                    p[e.to]=G[x][i];
                    cur[x]=i;
                    x=e.to;
                    break;
                }
            }
            if(!ok)
            {
                int m=n-1;
                for(unsigned i=0;i<G[x].size();i++)
                {
                    Edge& e=edges[G[x][i]];
                    if(e.cap>e.flow) m=min(m,d[e.to]);
                }
                if(--num[d[x]]==0) break;
                num[d[x]=m+1]++;
                cur[x]=0;
                if(x!=s) x=edges[p[x]].from;
            }
        }
        return flow;
    }
};
时间: 2024-10-09 21:45:17

HDU 1532 Drainage Ditches (网络流)的相关文章

HDU 1532 Drainage Ditches 最大排水量 网络最大流 Edmonds_Karp算法

题目链接:HDU 1532 Drainage Ditches 最大排水量 Drainage Ditches Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) Total Submission(s): 9641    Accepted Submission(s): 4577 Problem Description Every time it rains on Farmer John

HDU - 1532 - Drainage Ditches &amp;&amp; 3549 - Flow Problem (网络流初步)

Drainage Ditches Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) Total Submission(s): 10875    Accepted Submission(s): 5131 Problem Description Every time it rains on Farmer John's fields, a pond forms over Bessie'

HDU 1532 Drainage Ditches (最大网络流)

Drainage Ditches Time Limit : 2000/1000ms (Java/Other)   Memory Limit : 65536/32768K (Java/Other) Total Submission(s) : 5   Accepted Submission(s) : 3 Font: Times New Roman | Verdana | Georgia Font Size: ← → Problem Description Every time it rains on

HDU 1532 Drainage Ditches(最大流 EK算法)

题目网址:http://acm.hdu.edu.cn/showproblem.php?pid=1532 思路: 网络流最大流的入门题,直接套模板即可~ 注意坑点是:有重边!!读数据的时候要用"+="替换"=". 对网络流不熟悉的,给一篇讲解:http://www.cnblogs.com/ZJUT-jiangnan/p/3632525.html. ?(? ? ??)我是看这篇博客才入门的. 代码: 1 #include <cstdio> 2 #includ

hdu 1532 Drainage Ditches(最大流)

Drainage Ditches 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 drai

HDU 1532 Drainage Ditches 排水渠(网络流,最大流,入门)

题意:给出一个有向图,以及边上的容量上限,求最大流.(有重边,要将容量上限叠加) 思路:用最简单的EK+BFS解决.每次搜到一条到达终点的路径,就立刻退出,更新ans,然后再回头修改图中的当前flow状况(这就得靠记录路径了).当当前图没有到达终点的路径图,流已经饱和,可以结束程序了. 1 #include <bits/stdc++.h> 2 #define LL long long 3 #define pii pair<int,int> 4 #define INF 0x7f7f7

HDU 1532 Drainage Ditches

http://acm.hdu.edu.cn/showproblem.php?pid=1532 基础题. 1 #include<iostream> 2 #include<cstring> 3 #include<string> 4 #include<algorithm> 5 #include<queue> 6 using namespace std; 7 8 int n, m, flow; 9 int vis[205]; 10 //路径记录 11 i

hdu - 1532 Drainage Ditches (最大流)

http://acm.hdu.edu.cn/showproblem.php?pid=1532 求最大的流量,用dinic算法就好. 1 // Rujia Liu 2 // 因为图较大,所以采用Dinic而不是EdmondsKarp 3 // 得益于接口一致性,读者无须理解Dinic就能使用它. 4 #include<cstdio> 5 #include<cstring> 6 #include<queue> 7 #include<algorithm> 8 us

hdu 1532 Drainage Ditches(edmond-karp最大流算法)

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1532 #include <stdio.h> #include <queue> #include <string.h> #include <algorithm> #define INT_MAX (int)1e9 using namespace std; const int N = 207; int network[N][N], pre[N], used[N], f