最大流HLPP板子求调,悬赏2关注
  • 板块学术版
  • 楼主Deamer
  • 当前回复0
  • 已保存回复0
  • 发布时间2023/4/4 19:32
  • 上次更新2023/10/23 19:27:05
查看原帖
最大流HLPP板子求调,悬赏2关注
585962
Deamer楼主2023/4/4 19:32
#include<bits/stdc++.h>
using namespace std;
const int N=12e2+10,M=12e4+10;
int n,m,s,t;
int cnt=1;
struct Edge { int to,rev,w; } edge[M];
int degree[N],first_edge[N],cur_edge[N];
int front,q[N];
int heightest,gapHeightest,height[N];
int gapPre[N<<1],gapNxt[N<<1];
int lst[N],nxt[N];
int f[N];
int work;
vector<array<int,3> > e(M);
int ans;

inline bool cmp(Edge x,Edge y) { return x.to<y.to; }

inline int read(){
	int X=0; bool flag=1; char ch=getchar();
	while(ch<'0' || ch>'9') { if(ch=='-') flag=0; ch=getchar(); }
	while(ch>='0' && ch<='9') { X=(X<<1)+(X<<3)+ch-'0'; ch=getchar(); }
	if(flag) return X;
	return ~(X-1);
}

inline void add(int u,int v,int w){
	edge[cur_edge[u]++]={v,cur_edge[v],w};
	edge[cur_edge[v]++]={u,cur_edge[u]-1,0};
}

inline void PushLst(int u){
	int h=height[u];
	nxt[u]=lst[h];
	lst[h]=u;
}

inline void UpdHeight(int u,int h){
	if(height[u]!=n){
		gapNxt[gapPre[u]]=gapNxt[u];
		gapPre[gapNxt[u]]=gapPre[u];
	}
	if(h==n) return ;
	height[u]=h;
	gapHeightest=max(gapHeightest,h);
	if(f[u]){
		PushLst(u);
		heightest=max(heightest,h);
	}
	h+=n;
	gapPre[u]=h;
	gapNxt[u]=gapNxt[h];
	gapNxt[h]=u;
	gapPre[gapNxt[u]]=u;
}

inline void GlobalRelabel(){
	fill(height+1,height+1+n,n);
	work=0;
	height[t]=0;
	q[++front]=t;
	for(int i(1);i<=front;i++){
		int u=q[i];
		for(int j(first_edge[u]);j<(first_edge[u+1]);j++){
			auto& e=edge[j];
			int v=e.to,w=e.w;
			if(height[v]==n && w){
				UpdHeight(v,height[u]+1);
				q[++front]=v;
			}
		}
	}
	heightest=height[q[front]];
}

inline void Push(int u,Edge &e){
	int v=e.to,rev=e.rev,&w=e.w,flow=min(f[u],w);
	if(flow){
		if(!f[v] && v!=s && v!=t) PushLst(v);
		w-=flow; edge[rev].w+=flow;
		f[u]-=flow; f[v]+=flow;
	}
}

inline void Discharge(int u){
	++work;
	int h=n;
	for(int i(cur_edge[u]);i<cur_edge[i+1];cur_edge[u]++,i++){
		auto& e=edge[i];
		int v=e.to,w=e.w;
		if(w){
			if(height[u]==height[v]+1){
				Push(u,e);
				if(!f[v]) break;
			}
			else h=min(h,height[u]+1);
		}
	}
	if(gapNxt[gapNxt[height[u]+n]]!=height[u]+n) UpdHeight(u,h);
	else {
		for(int i(height[u]);i<=heightest;i++){
			for(int j(gapNxt[height[u]+n]);j<n;j=gapNxt[j]){
				height[j]=n;
			}
		}
		gapHeightest=height[u]-1;
	}
}

inline void HLPP(){
	for(int u(1);u<=n;u++){
		sort(edge+first_edge[u],edge+first_edge[u+1]-1,cmp);
		for(int i(first_edge[u]);i<first_edge[u+1];i++){
			auto& e=edge[i];
			int rev=e.rev;
			edge[rev].rev=i;
		}
	}
	GlobalRelabel();
	for(int i(first_edge[s]);i<first_edge[s+1];i++){
		auto& e=edge[i];
		int v=e.to,rev=e.rev,&w=e.w;
		edge[rev].w+=w; f[v]+=w;
		w-=w;
	}
	copy(first_edge+1,first_edge+1+n,cur_edge);
	for(;heightest;heightest--){
		for(int u(lst[heightest]);u;u=nxt[u]){
			if(height[u]==heightest){
				Discharge(u);
				if(work>=n<<2) GlobalRelabel();
			}
		}
	}
}

int main(){
	n=read(); m=read(); s=read(); t=read();
	for(auto x:e){
		x[0]=read(); x[1]=read(); x[2]=read();
		degree[x[0]]++; degree[x[1]]++; 
	}
	for(int i(1);i<=n;i++){
		first_edge[i]=cnt;
		cnt+=degree[i];
	}
	first_edge[n+1]=cnt;
	copy(first_edge+1,first_edge+2+n,cur_edge);
	for(auto x:e) add(x[0],x[1],x[2]);
	HLPP();
	printf("%d\n",f[t]);
	return 0;
}
2023/4/4 19:32
加载中...