蒟蒻求条
查看原帖
蒟蒻求条
1007817
hutao_sdog楼主2024/7/5 11:15

10分高级代码,其他全wa了

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N=1e6+10;
const ll inf=1e15;
ll n,m,s,t,S,T,max_flow=0,min_cost=0;
ll in[N],out[N];
ll d[N],flow[N],vis[N];
ll pre[N];
ll head[N],cnt=0;
struct node{
	ll v,w,dis,nex;
}e[N];
void add(ll u,ll v,ll w,ll dis){
	e[++cnt].v=v;
	e[cnt].w=w;
	e[cnt].dis=dis;
	e[cnt].nex=head[u];
	head[u]=cnt;
	
	e[++cnt].v=u;
	e[cnt].w=0;
	e[cnt].dis=-dis;
	e[cnt].nex=head[v];
	head[v]=cnt;
}
bool spfa(){
	queue<ll> q;
	for(int i=0;i<=T;i++){
		d[i]=inf;
		vis[i]=0;
	}
	q.push(S);
	d[S]=0;
	vis[S]=1;
	flow[S]=inf;
	while(!q.empty()){
		ll u=q.front();
		q.pop();
		vis[u]=0;
		for(int i=head[u];i;i=e[i].nex){
			if(!e[i].w) continue;
			ll v=e[i].v,w=e[i].w,dis=e[i].dis;
			if(d[v]>d[u]+dis){
				d[v]=d[u]+dis;
				flow[v]=min(flow[u],w);
				pre[v]=i;
				if(!vis[v]){
					q.push(v);
					vis[v]=1;
				}
			}
		}
	}
	if(d[T]==inf) return 0;
	return 1;
}
int main(){
	cin>>n>>m>>s>>t;
	S=0;
	T=n+1;
	for(int i=1;i<=m;i++){
		ll u,v,w,dis;
		cin>>u>>v>>w>>dis;
		if(dis>=0) add(u,v,w,dis);
		else{
			//对于负费用边,先让其直接满流,然后加入一条与原来流量相同,费用相反的边用于退流
			out[u]+=w;
			in[v]+=w;
			min_cost=min_cost+w*dis;
			add(v,u,w,-dis);
		}
	}
	for(int i=1;i<=n;i++){
		if(in[i]>out[i]) add(S,i,in[i]-out[i],0);
		if(in[i]<out[i]) add(i,T,out[i]-in[i],0);
	}
	add(t,s,inf,0);
	while(spfa()){
		ll now=T;
		max_flow+=flow[T];
		min_cost+=d[T]*flow[T];
		while(now!=S){
			ll p=pre[now];
			e[p].w-=flow[T];
			if(p%2==1){
				e[p+1].w+=flow[T];
				now=e[p+1].v;
			}
			else{
				e[p-1].w+=flow[T];
				now=e[p-1].v;
			}
		}
	}
	max_flow=0;
	for(int i=head[t];i;i=e[i].nex){
		ll v=e[i].v,w=e[i].w;
		if(v==s&&w==inf){
			if(i%2==1){
				max_flow=e[i+1].w;
				e[i].w=e[i+1].w=0;//拆虚边
			}
			else{
				max_flow=e[i-1].w;
				e[i].w=e[i-1].w=0;
			}
		}
	}
	for(int i=m*2+1;i<=cnt;i++) e[i].w=0;
	S=s;
	T=t;
	while(spfa()){
		ll now=T;
		max_flow+=flow[T];
		min_cost+=d[T]*flow[T];
		while(now!=S){
			ll p=pre[now];
			e[p].w-=flow[T];
			if(p%2==1){
				e[p+1].w+=flow[T];
				now=e[p+1].v;
			}
			else{
				e[p-1].w+=flow[T];
				now=e[p-1].v;
			}
		}
	}
	cout<<max_flow<<" "<<min_cost;
	return 0;
}
2024/7/5 11:15
加载中...