洛谷3376网络最大流模板

题目:https://www.luogu.org/problemnew/show/P3376

模板。

1.当前弧优化的地方用了&;

2.用了《算法竞赛进阶指南》里的构造函数。

#include<iostream>
#include<cstdio>
#include<cstring>
#include<queue>
#define ll long long
using namespace std;
int n,m,s,t,head[10005],x,y,xnt=1;
int dfn[10005],hd,tl,cur[10005];
ll z,mxflow;
const ll INF=0x7fffffff;
struct Edge{
    int next,to;
    ll cap;
    Edge(int ne=0,int t=0,ll ca=0):next(ne),to(t),cap(ca) {}
}edge[200005];
queue<int> q;
bool bfs()
{
    memset(dfn,0,sizeof dfn);
    dfn[s]=1;
    q.push(s);
    while(!q.empty())
    {
        int k=q.front();q.pop();
        for(int i=head[k];i;i=edge[i].next)
            if(!dfn[edge[i].to]&&edge[i].cap)
            {
                dfn[edge[i].to]=dfn[k]+1;
                q.push(edge[i].to);
            }
    }
    return dfn[t];
}
ll dinic(int k,ll flow)
{
    if(k==t)return flow;
    ll used=0;
    for(int& i=cur[k],v;i;i=edge[i].next)//当前弧(引用以修改) 
        if(dfn[v=edge[i].to]==dfn[k]+1&&edge[i].cap)
        {
            ll tmp=dinic(v,min(flow-used,edge[i].cap));
            if(!tmp)dfn[v]=0;//////剪枝 
            edge[i].cap-=tmp;
            edge[i^1].cap+=tmp;
            used+=tmp;
            if(used==flow)return used;
        }
    return used;
}
int main()
{
    scanf("%d%d%d%d",&n,&m,&s,&t);
    for(int i=1;i<=m;i++)
    {
        scanf("%d%d%lld",&x,&y,&z);
        edge[++xnt]=Edge(head[x],y,z);
        head[x]=xnt;
        edge[++xnt]=Edge(head[y],x,0);
        head[y]=xnt;
    }
    while(bfs())
    {
        memcpy(cur,head,sizeof head);
        mxflow+=dinic(s,INF);
    }
    printf("%lld",mxflow);
    return 0;
}

 

posted on 2018-03-19 22:29  Narh  阅读(118)  评论(0编辑  收藏  举报

导航