求助 EK 跑费用流
查看原帖
求助 EK 跑费用流
239895
Yusani_huh楼主2022/7/11 11:10

基本上对着第一篇题解写的,但是 T 了 #2 7 8 9 10,判断是出现了负环,不知道为什么 /kk

#include<bits/stdc++.h>
using namespace std;
#define N 80053
#define M 7000003
#define LL long long
#define INF 0x3f3f3f3f
int n,m,p[43],te[103][43],sum,ds[N],ck[N];
int S,T,q[N],d[N],incf[N],pre[N];
int h[N],to[M],ne[M],f[M],w[M],idx;
bool st[N];
void add(int u,int v,int c,int d){  //加边
	to[idx]=v,f[idx]=c,w[idx]=d,ne[idx]=h[u],h[u]=idx++;
	to[idx]=u,f[idx]=0,w[idx]=-d,ne[idx]=h[v],h[v]=idx++;
}
bool spfa(){  //费用流模板
	int hh=0,tt=1;
	for(int i=S;i<=T;++i) d[i]=INF,incf[i]=pre[i]=0;
	q[hh]=S,d[S]=0,incf[S]=INF;
	while(hh!=tt){
		int u=q[hh++];
		if(hh==N) hh=0;
		st[u]=false;
		for(int i=h[u];~i;i=ne[i]){
			int v=to[i];
			if(f[i]&&d[v]>d[u]+w[i]){
				d[v]=d[u]+w[i],pre[v]=i;
				incf[v]=min(incf[u],f[i]);
				if(!st[v]){
					q[tt++]=v,st[v]=true;
					if(tt==N) tt=0;
				}
			}
		}
	}
	return incf[T]>0;
}
int EK(){  //跑SPFA的同时动态加边
	int cost=0;
	while(spfa()){
		int t=incf[T];
		cost+=t*d[T];
		for(int i=T;i!=S;i=to[pre[i]^1])
			f[pre[i]]-=t,f[pre[i]^1]+=t;
		int tmp=to[pre[T]^1];
		add(tmp+1,T,1,0);
		for(int i=1;i<=n;++i)
			add(i+m*sum,tmp+1,1,te[i][ck[tmp]]*(ds[tmp]+1));
	}
	return cost;
}
int main(){
	memset(h,-1,sizeof h);
	scanf("%d%d",&n,&m);
	for(int i=1;i<=n;++i)
		scanf("%d",&p[i]),sum+=p[i];
	S=0,T=sum*m+n+1;
	for(int i=1;i<=n;++i) add(S,i+sum*m,p[i],0);
	for(int i=1;i<=n;++i)
		for(int j=1;j<=m;++j){
			scanf("%d",&te[i][j]);
			add(i+sum*m,(j-1)*sum+1,1,te[i][j]);
		}
	for(int i=1;i<=m;++i)
		for(int j=1;j<=sum;++j){
			int tmp=(i-1)*sum+j;
			ck[tmp]=i,ds[tmp]=j;
		}
	for(int i=1;i<=m;++i) add((i-1)*sum+1,T,1,0);
	printf("%d\n",EK());
	return 0;
}
2022/7/11 11:10
加载中...