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;
}
posted @ 2018-07-21 00:24  zball  阅读(506)  评论(0编辑  收藏  举报