社区讨论

悬关,费用流模板求调

学术版参与者 2已保存回复 1

讨论操作

快速查看讨论及其快照的属性,并进行相关操作。

当前回复
1 条
当前快照
1 份
快照标识符
@lwp1yquc
此快照首次捕获于
2024/05/27 22:17
2 年前
此快照最后确认于
2024/05/28 13:39
2 年前
查看原帖
用的Dinic+SPFA 最后四个点全TLE,啾啾这个娃吧
CPP
#include<cmath>
#include<cstdio>
#include<iostream>
#define int long long
int ans2,n,m,s,t,to[100005],head[5005],last[100005],w[100005],now[5005],ct=1,l[5005],f[100005],dis[5005],bz[5005];
using namespace std;
void add(int a,int b,int c,int cc){
	to[++ct]=b,last[ct]=head[a],head[a]=ct,w[ct]=c,f[ct]=cc;
	to[++ct]=a,last[ct]=head[b],head[b]=ct,w[ct]=0,f[ct]=-cc;
}
bool bfs(){
	for(int i=1;i<=n;i++) dis[i]=2147483647,now[i]=head[i],bz[i]=0;
	dis[s]=0;
	int i=0,j=0;
	l[i]=s;
	while(i<=j){
		bz[l[i]]=0;
		for(int k=head[l[i]];k!=0;k=last[k]){
			if(dis[to[k]]>dis[l[i]]+f[k]&&w[k]>0){
				dis[to[k]]=dis[l[i]]+f[k];
				if(bz[to[k]]==0) l[++j]=to[k],bz[to[k]]=1;
			}
		}
		i++;
	}
	
	if(dis[t]==0) return 0;
	else return 1;
}
int dg(int ii,int minn){
	if(ii==t) return minn;
	for(int i=now[ii];i!=0;i=last[i]){
		now[ii]=i;
		if(w[i]!=0&&dis[to[i]]==dis[ii]+f[i]){
			int v=dg(to[i],min(w[i],minn));
			if(v>0){
				ans2+=v*f[i];
				w[i]-=v;
				w[i^1]+=v;
				return v;
			}
		}
	}
	return 0;
}
signed main(){
	freopen("a.txt","r",stdin);
	scanf("%lld%lld%lld%lld",&n,&m,&s,&t);
	for(int i=1;i<=m;i++){
		int a,b,c,cc;
		scanf("%lld%lld%lld%lld",&a,&b,&c,&cc);
		add(a,b,c,cc);
	}
	int ans=0;
	while(bfs()==1){
		int k=dg(s,1e18);
		if(k==0) break;
		else ans+=k;
	}
	printf("%lld %lld",ans,ans2);
}

回复

1 条回复,欢迎继续交流。

正在加载回复...