1. 程式人生 > >最大流 [USACO4.2]草地排水Drainage Ditches

最大流 [USACO4.2]草地排水Drainage Ditches

Background

在農夫約翰的農場上,每逢下雨,貝茜最喜歡的三葉草地就積聚了一潭水。這意味著草地被水淹沒了,並且小草要繼續生長還要花相當長一段時間。因此,農夫約翰修建了一套排水系統來使貝茜的草地免除被大水淹沒的煩惱(不用擔心,雨水會流向附近的一條小溪)。作為一名一流的技師,農夫約翰已經在每條排水溝的一端安上了控制器,這樣他可以控制流入排水溝的水流量。

Description

農夫約翰知道每一條排水溝每分鐘可以流過的水量,和排水系統的準確佈局(起點為水潭而終點為小溪的一張網)。需要注意的是,有些時候從一處到另一處不只有一條排水溝。

根據這些資訊,計算從水潭排水到小溪的最大流量。對於給出的每條排水溝,雨水只能沿著一個方向流動,注意可能會出現雨水環形流動的情形。

Input

第1行: 兩個用空格分開的整數N (0 <= N <= 200) 和 M (2 <= M <= 200)。N是農夫John已經挖好的排水溝的數量,M是排水溝交叉點的數量。交點1是水潭,交點M是小溪。

第二行到第N+1行: 每行有三個整數,Si, Ei, 和 Ci。Si 和 Ei (1 <= Si, Ei <= M) 指明排水溝兩端的交點,雨水從Si 流向Ei。Ci (0 <= Ci <= 10,000,000)是這條排水溝的最大容量。

Output

輸出一個整數,即排水的最大流量。

裸的網路流,答案即為從\(1\)\(m\)的最大流。

注意看清我的輸入,穩穩\(AC\)

程式碼

#include<cstdio>
#include<algorithm>
#include<cstring>
#include<queue> 
#include<iostream>
#define clear(a,b) memset(a,b,sizeof a)
#define R register

using namespace std;

const int gz=1500000+10;

inline void in(R int &x)
{
    R int f=1;x=0;char s=getchar();
    while(!isdigit(s)){if(s=='-')f=-1;s=getchar();}
    while(isdigit(s)){x=x*10+s-'0';s=getchar();}
    x*=f;
}

int head[gz],depth[gz],tot,n,m,cur[gz],s,t;

struct cod{int u,v,w;}edge[gz];

inline void add(R int x,R int y,R int z)
{
    edge[++tot].u=head[x];
    edge[tot].v=y;
    edge[tot].w=z;
    head[x]=tot;
}

inline bool bfs()
{
    clear(depth,0);queue<int>q;
    depth[s]=1;q.push(s);
    for(R int i=1;i<=n;i++)cur[i]=head[i];
    while(!q.empty())
    {
        R int u=q.front();q.pop();
        for(R int i=head[u];i!=-1;i=edge[i].u)
        {
            if(depth[edge[i].v]==0 and edge[i].w>0)
            {
                depth[edge[i].v]=depth[u]+1;
                q.push(edge[i].v);
            }
        }
    }
    return depth[t];
}

inline int dfs(R int u,R int dist)
{
    if(u==t or !dist)return dist;
    R int di=0,f;
    for(R int i=cur[u];i!=-1;i=edge[i].u)
    {
        cur[u]=i;
        if(depth[edge[i].v]==depth[u]+1 and (f=dfs(edge[i].v,min(edge[i].w,dist))))
        {
            di+=f;dist-=f;
            edge[i].w-=f;edge[i^1].w+=f;
            if(dist==0)break;
        }
    }
    return di;
}

inline int dinic()
{
    R int ans=0;
    while(bfs())ans+=dfs(s,214748364);
    return ans;
}

int main()
{
    in(m),in(n);s=1,t=n;
    clear(head,-1);tot=-1;
    for(R int i=1,x,y,z;i<=m;i++)
    {
        in(x),in(y),in(z);
        add(x,y,z);add(y,x,0);
    }
    printf("%d\n",dinic());
}