一点疑惑
查看原帖
一点疑惑
390575
AChun楼主2022/1/26 22:59

n范围小于等于5000,见如下代码

当我取n为5000+200时,会爆三个点

把n改为101000时,就A了

QWQ

#include<iostream>
#include<cstdio>
#include<cstring>
#define N 5200
#define M 105000
using namespace std;
const int INF = 1e8;
int n,m,s,t,x,y,z,w;
int head[N],Next[M],ver[M],edge[M],tot=-1;
int q[N],incf[N],val[M],d[N],pre[N];
bool st[N];

void ADD(int x,int y,int z,int w){
	ver[++tot]=y;edge[tot]=z;
	val[tot]=w;Next[tot]=head[x];head[x]=tot;
	ver[++tot]=x;edge[tot]=0;
	val[tot]=-w;Next[tot]=head[y];head[y]=tot;
} 

bool spfa(){
	int f=0,r=0;
	memset(d,0x3f,sizeof(d));
	memset(incf,0,sizeof(incf));
	q[r++]=s;d[s]=0;incf[s]=INF;
	while(f<r){
		int x=q[f++];
		if(f==N) f=0;
		st[x]=false;
		for(int i=head[x];~i;i=Next[i]){
			int y=ver[i];
			if(edge[i]&&d[y]>d[x]+val[i]){
				d[y]=d[x]+val[i];
				pre[y]=i;
				incf[y]=min(edge[i],incf[x]);
				if(!st[y]){
					q[r++]=y;st[y]=true;
					if(r==N) r=0;
				}
			}
		}
	}
	return incf[t]>0;
}

void EK(int &flow,int &cost){
	flow=cost=0;
	while(spfa()){
		int k=incf[t];
		flow+=k;cost+=k*d[t];
		for(int i=t;i!=s;i=ver[pre[i]^1]){
			edge[pre[i]]-=k;
			edge[pre[i]^1]+=k;
		}
	}
}

int main(){
	memset(head,-1,sizeof(head));
	scanf("%d%d%d%d",&n,&m,&s,&t);
	while(m--){
		scanf("%d%d%d%d",&x,&y,&z,&w);
		ADD(x,y,z,w);
	}
	int flow,cost; 
	EK(flow,cost);
	printf("%d %d\n",flow,cost);
	return 0;
}


2022/1/26 22:59
加载中...