HLPP

LOJ 最大流加强版

#include <bits/stdc++.h>
const int inf=0x7fffffff;
const int maxn=1210;
const int maxh=1<<20;
using namespace std;
int f[maxn][maxn];
typedef unsigned short u16;
vector<u16> out[maxn],act[maxn];
#define count cnt
struct nodelist{u16 l,r;}hlist[maxn];
u16 height[maxn],count[maxn],hlisthead[maxn],que[maxn];
short high,highact;
int excess[maxn];
int n,m,s,t;
void ins(int t,int h){
    int q=hlisthead[h];
    int l=q?q:t;
    int r=q?hlist[q].r:t;
    hlist[t].l=l;
    hlist[l].r=t;
    hlist[t].r=r;
    hlist[r].l=t;
    hlisthead[h]=t;
    height[t]=h;
    ++count[h];
}
void del(int t,int h){
    int l=hlist[t].l;
    int r=hlist[t].r;
    hlist[r].l=l;
    hlist[l].r=r;
    if(hlisthead[h]==t)
        hlisthead[h]=l==t?0:l;
    --count[h];
}
void ae(int u,int v,int c){f[u][v]+=c;}
void regularize(){
    for(int i=1;i<=n;++i)
        for(int j=i+1;j<=n;++j)
            if(f[i][j]||f[j][i])
                out[i].push_back(j),out[j].push_back(i);
}
void push(int u,int v){
    int df=min(excess[u],f[u][v]);
    f[u][v]-=df;f[v][u]+=df;
    excess[u]-=df;excess[v]+=df;
    if(excess[v]>0&&excess[v]<=df)act[height[v]].push_back(v);
}
void grel(){
    fill(height,height+(n+1),n);
    memset(count,0,sizeof count);
    memset(hlisthead,0,sizeof hlisthead);
    int ql=0,qr=0;
    for(ins(t,0),que[qr++]=t;ql!=qr;){
        int u=que[ql++],h=height[u]+1;
        for(int v:out[u])
            if(height[v]==n&&f[v][u])
                ins(v,h),que[qr++]=v;
    }act[0].clear();
    for(int i=1;i<=n;++i)
        if(excess[i]>0)act[height[i]].push_back(i);
    high=highact=height[que[qr-1]];
}
void discharge(int u){
    int nm=n,h=height[u];
    for(int v:out[u])if(f[u][v])
        if(h==height[v]+1){
            push(u,v);if(!excess[u])return;
        }else nm=min(nm,height[v]+1);
    if(count[h]==1){
        for(int i=h;i<=high;++i)
            while(hlisthead[i])height[hlisthead[i]]=n,del(hlisthead[i],i);
        high=h-1;
    }else{
        del(u,h),height[u]=nm;
        if(nm==n)return;
        ins(u,nm);high=max(high,highact=nm);
        act[nm].push_back(u);
    }
}
int hlpp(){
    if(s==t)return 0;
    highact=high=0;height[s]=n;
    excess[s]=inf;excess[t]=-inf;
    for(int i:out[s])push(s,i);grel();
    for(int u;highact>=0;)if(act[highact].empty())--highact;else u=act[highact].back(),act[highact].pop_back(),discharge(u);
    return excess[t]+inf;
}
int main(){
    scanf("%d%d%d%d",&n,&m,&s,&t);
    for(int i=0,u,v,f;i<m;++i){
        scanf("%d%d%d",&u,&v,&f);
        ae(u,v,f);
    }regularize();
    printf("%d\n",hlpp());
    return 0;
}

猜你喜欢

转载自www.cnblogs.com/tmzbot/p/9344729.html