模板:DINIC(多路增广)+当前弧优化

题目见USACO草地排水一题

#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
inline ll read()
{
    char k=0;char ls;ls=getchar();for(;ls<'0'||ls>'9';k=ls,ls=getchar());
    ll x=0;for(;ls>='0'&&ls<='9';ls=getchar())x=x*10+ls-'0';
    if(k=='-')x=0-x;return x;
}

ll n,m;
struct E
{
    ll edge;
    ll zhi;
    ll s;
}a[3000];
ll last[3000];
ll back;
ll ans;
ll d[3000];

inline ll bfs()
{
    queueq;
    memset(d,0,sizeof(d));
    d[1]=1;
    q.push(1);
    while(!q.empty())
    {
        ll u=q.front();
        q.pop();
        for(int j=last[u];j;j=a[j].zhi)
        if(a[j].s>0&&d[a[j].edge]==0)
        {
            d[a[j].edge]=d[u]+1;
            q.push(a[j].edge);
            if(a[j].edge==n)
            return 1;
        }
    }
    return 0;
}


inline ll dinic(ll x,ll flow)
{
    ll left=0;
    if(x==n)
    return flow;
    for(int j=last[x];j;j=a[j].zhi)
      if(a[j].s>0&&d[a[j].edge]==d[x]+1)
        {
            ll temp=dinic(a[j].edge,min(flow,a[j].s));
            if(!temp)
            {d[a[j].edge]=0;continue;}
            a[j].s-=temp;
            a[j^1].s+=temp;
            left+=temp;
            flow-=temp;
            if(!flow)break;
        }
    if(!flow)d[x]=-1;
    return left;
}



int main()
{
    //freopen("dt.in","r",stdin);
    //freopen("dt.out","w",stdout);
    m=read();n=read();
    for(int i=1;i<=m;++i)
    {
        ll a1=read(),b1=read(),c1=read(); 
        a[++back].edge=b1;//建立正向边 
        a[back].zhi=last[a1];
        a[back].s=c1;
        last[a1]=back;

        a[++back].edge=a1;//建立逆向边 
        a[back].zhi=last[b1];
        a[back].s=0;
        last[b1]=back;
    }
    while(bfs())
    ans+=dinic(1,INT_MAX);
    cout<//fclose(stdin);
    //fclose(stdout);
    return 0;
}

你可能感兴趣的:(网络流)