网络流 HLPP 板子

#include<bits/stdc++.h>
using namespace std;
const int MM=4e5+5,inf=0x3f3f3f3f;
int n,m,s,t,tot=1,a;
int nxt[MM],head[MM],to[MM],w[MM];
int h[MM],e[MM],gap[MM],in[MM];
struct cmp
{
    bool operator()(int a,int b) const 
    {
        return h[a]<h[b];
    } 
}; 
priority_queue<int,vector<int>,cmp> q; 
void add(int u,int v,int flow)
{
    nxt[++tot]=head[u];
    to[tot]=v;
    w[tot]=flow;
    head[u]=tot;
}
bool bfs()
{
    int q[1200],l=1,r=1,now;
    memset(h,0x3f,sizeof(h));
    q[1]=t;h[t]=0;
    while(r>=l)
    {
        now=q[l++];
        for(int i=head[now];i;i=nxt[i])
            if(w[i^1]&&h[to[i]]>h[now]+1)
                h[to[i]]=h[now]+1,q[++r]=to[i];
    }
    return h[s]!=inf;
}
void push(int now)
{
    int flow;
    for(int i=head[now];i;i=nxt[i])
        if(w[i]&&h[to[i]]+1==h[now])
        {
            flow=min(e[now],w[i]);
            w[i]-=flow;w[i^1]+=flow;e[now]-=flow,e[to[i]]+=flow;
            if(to[i]!=s&&to[i]!=t&&!in[to[i]])
                q.push(to[i]),in[to[i]]=1;
            if(!e[now])
                break;
        }
    
} 
void relabel(int now)
{
    h[now]=inf;
    for(int i=head[now];i;i=nxt[i])
        if(w[i]&&h[to[i]]+1<h[now])
            h[now]=h[to[i]]+1;
    return;
}
void pp()
{
        for(int i=1;i<=n;i++)
        cout<<i<<' ';
    cout<<endl;
    for(int i=1;i<=n;i++)
        cout<<e[i]<<' ';
    cout<<endl;
}
int main()
{
    cin>>n>>m>>s>>t;
    int u,v,a,now;
    for(int i=1;i<=m;i++)
        cin>>u>>v>>a,add(u,v,a),add(v,u,0);
    
    if(!bfs())
    {
        cout<<0;
        return 0;
    }
    h[s]=n;
    for(int i=1;i<=n;i++)
        if(h[i]<inf)
            ++gap[h[i]];
    for(int i=head[s];i;i=nxt[i])
    {
        int flow=w[i];
        w[i]-=flow;w[i^1]+=flow;e[s]-=flow;e[to[i]]+=flow;
        if(to[i]!=s&&to[i]!=t&&!in[to[i]])
            q.push(to[i]),in[to[i]]=1;
    }

    while(!q.empty())
    {
        now=q.top();q.pop();in[now]=0;push(now);//cout<<now<<endl;
        if(e[now])
        {
            if(!--gap[h[now]]) 
                for(int i=1;i<=n;i++)
                    if(i!=s&&i!=t&&h[i]>h[now]&&h[i]<n+1)
                        h[i]=n+1;
            relabel(now);++gap[h[now]];
            q.push(now);in[now]=1;
        }
    }
    cout<<e[t];
    return 0;
} 
~~~

 

posted @ 2021-12-24 15:29  T_X蒻  阅读(54)  评论(1编辑  收藏  举报