杀鸡焉用牛刀 HLPP 算法
查看原帖
杀鸡焉用牛刀 HLPP 算法
1052693
sangshang楼主2023/11/18 17:19
#include<bits/stdc++.h>
#define inf LONG_LONG_MAX
#define int long long
#define re register
#define maxn 1203
//using namespace std;
struct edge{
    int flow,nex,to;
    edge(int to,int flow,int nex):to(to),flow(flow),nex(nex) {}
    edge() {}
};
std::vector<edge>a[maxn];
std::vector<int>e,cnt,h,list[maxn],que;
typedef std::list<int> List;
List dlist[maxn];
typedef std::vector<edge>::iterator Iterator;
std::vector<List::iterator>iter;
int hst,nowh;
inline void add(const int from,const int to,const int flow){
    a[from].push_back(edge(to,flow,a[to].size())),a[to].push_back(edge(from,0,a[from].size()-1));
}
inline void relabel(int n ,int t){
    h.assign(n,n),h[t]=0,cnt.assign(n,0),que.clear(),que.resize(n+1);
    int qt=0,qh=0;
    for(que[qt++]=t;qh<qt;){
        int u=que[qh++],het=h[u]+1;
        for(Iterator p=a[u].begin();p!=a[u].end();++p){
            if(h[p->to]==n&&a[p->to][p->nex].flow){h[p->to]=het,que[qt++]=(p->to),cnt[het]++;}
        }
    }
    for(int i=0;i<=n;++i){list[i].clear(),dlist[i].clear();}
    for(int i=0;i<n;++i){if(h[i]<n){iter[i]=dlist[h[i]].insert(dlist[h[i]].begin(),i);}if(e[i]>0){list[h[i]].push_back(i);}}
    hst=nowh=h[que[qt-1]];
}
inline void push_edge(int u,edge &edg){
    int v=edg.to,df=std::min(e[u],edg.flow);
    e[u]-=df,e[v]+=df,edg.flow-=df,a[v][edg.nex].flow+=df;
    if(e[v]!=0&&e[v]<=df){list[h[v]].push_back(v);}
}
inline void push_node(int u,int n){
    int nh=n;
    for(Iterator p=a[u].begin();p!=a[u].end();++p){
        if(p->flow>0){if(h[u]==h[p->to]+1){push_edge(u,*p);}if(e[u]){nh=std::min(nh,h[p->to]+1);}else{return;}}
    }
    int het=h[u];
    if(cnt[het]==1){
        for(int i=het;i<=nowh;++i){
            for(List::iterator p=dlist[i].begin();p!=dlist[i].end();++p){h[*p]=n;}
            cnt[i]=0,dlist[i].clear();
        }
        hst=het-1;
    }else{
        cnt[het]--;iter[u]=dlist[het].erase(iter[u]);
        if(nh==n){return;}
        h[u]=nh,cnt[nh]++,iter[u]=dlist[nh].insert(dlist[nh].begin(),u),hst=std::max(hst,nowh=nh),list[nh].push_back(u);
    }
}
inline int HLPP(int n,int s,int t){
    if(s==t){return 0;}
    h.assign(n,0),hst=0,nowh=0,iter.resize(n),h[s]=n;
    for(int i=0;i<n;++i){if(i!=s){iter[i]=dlist[h[i]].insert(dlist[h[i]].begin(),i);}}
    cnt.assign(n,0),cnt[0]=n-1,e.assign(n,0),e[s]=inf,e[t]=-inf;
    for(Iterator p=a[s].begin();p!=a[s].end();++p){push_edge(s,*p);}
    relabel(n,t);
    for(int u;nowh;){
        if(list[nowh].empty()){--nowh;continue;}
        u=list[nowh].back(),list[nowh].pop_back(),push_node(u,n);
    }
    return e[t]+inf;
}
inline int read(){
    bool fc=false;int ret=0;char c=getchar();
    while(c<'0'||c>'9'){if(c=='-'){fc=true;}c=getchar();}
    while(c>='0'&&c<='9'){ret=ret*10+c-'0',c=getchar();}
    return fc?-ret:ret;
}
int n,m,s,t,u,v,f;
signed main(){
    n=read(),m=read(),s=read(),t=read();
    for(int i=0;i<m;++i){u=read(),v=read(),f=read();add(u,v,f);}
    printf("%lld",HLPP(n+1,s,t));
    return 0;
}
2023/11/18 17:19
加载中...