【模板】 HLPP——最高标号预流推进

模板题联赛后慢慢更新~
(这个过不了那个毒瘤题的,你们得卡卡常什么的~)

#include<bits/stdc++.h>
using namespace std;
const int N=2e4+5;
const int M=2e5+5;
const int inf=0x3f3f3f3f;
int n,m,s,t,tot=1;
int v[M<<1],w[M<<1],next[M<<1];
int head[N],h[N],still[N],gap[N<<1],vis[N];
struct cmp
{
    inline bool operator()(int a,int b)const
    {
        return h[a]<h[b];
    }
};

queue<int>q1;
priority_queue<int,vector<int>,cmp> q2;

inline int rad()
{
    int x=0,f=1;char c;
    while(c<'0'||c>'9'){if(c=='-')f=-1;c=getchar();}
    while(c>='0'&&c<='9')x=(x<<3)+(x<<1)+c-'0',c=getchar();
    return x*f;
}

inline void addedge(int a,int b,int c)
{
    v[++tot]=b,w[tot]=c,next[tot]=head[a],head[a]=tot;
}

inline bool bfs()
{
    int now;
    register int i;
    memset(h,0x3f,sizeof(h));
    h[t]=0;q1.push(t);
    while(!q1.empty())
    {
        now=q1.front();q1.pop();
        for(i=head[now];i;i=next[i])
            if(w[i^1]&&h[v[i]]>h[now]+1)
                h[v[i]]=h[now]+1,q1.push(v[i]);
    }
    return h[s]!=inf; 
}

inline void push(int now)
{
    int d;register int i;
    for(i=head[now];i;i=next[i])
        if(w[i]&&h[v[i]]+1==h[now])
        {
        	d=min(still[now],w[i]);
        	w[i]-=d;w[i^1]+=d;
        	still[now]-=d;still[v[i]]+=d;
        	if(v[i]!=s&&v[i]!=t&&!vis[v[i]])
                q2.push(v[i]),vis[v[i]]=1;
            if(!still[now])break; 
        }
    return;
} 

inline void relabel(int now)
{
    register int i; 
    h[now]=inf;
    for(i=head[now];i;i=next[i])
        if(w[i]&&h[v[i]]+1<h[now])
            h[now]=h[v[i]]+1;
    return;
} 

inline int hlpp()
{
    int now,d;
    register int i;
    if(!bfs())return 0;
    h[s]=n;
    for(i=1;i<=n;i++)
        if(h[i]<inf)
            ++gap[h[i]];
    for(i=head[s];i;i=next[i])
        if(d=w[i])
        {
        	w[i]-=d;w[i^1]+=d;
        	still[s]-=d;still[v[i]]+=d;
        	if(v[i]!=s&&v[i]!=t&&!vis[v[i]])
        	q2.push(v[i]),vis[v[i]]=1;
        }
    while(!q2.empty())
    {
        vis[now=q2.top()]=0;q2.pop();push(now);
        if(still[now])
        {
            if(!--gap[h[now]])
                for(i=1;i<=n;i++)
                    if(i!=s&&i!=t&&h[i]>h[now]&&h[now]<n+1)
                        h[i]=n+1;
            relabel(now);++gap[h[now]];
            q2.push(now);vis[now]=1;
        }
    }
    return still[t];
}

signed main()
{
    int u,v,w;
    n=rad();m=rad();s=rad();t=rad();
    while(m--)
    {
        u=rad();v=rad();w=rad();
        addedge(u,v,w);addedge(v,u,0);
    }
    printf("%d",hlpp());
    
}
发布了44 篇原创文章 · 获赞 16 · 访问量 7273

猜你喜欢

转载自blog.csdn.net/Cyan_rose/article/details/83592844