社区讨论

费用流板子求调

P3381【模板】最小费用最大流参与者 3已保存回复 5

讨论操作

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

当前回复
5 条
当前快照
1 份
快照标识符
@lt834536
此快照首次捕获于
2024/03/01 11:18
2 年前
此快照最后确认于
2024/03/01 16:43
2 年前
查看原帖
洛谷上全re,但下数据本地测是没问题的
CPP
#include <bits/stdc++.h>
#define int long long
using namespace std;
inline int read(){
	char ch=getchar();int f=1,x=0;
	while(ch<'0'||ch>'9'){if(ch=='-') f=-1;ch=getchar();}
	while(ch>='0'&&ch<='9'){x=(x<<3)+(x<<1)+(ch^48);ch=getchar();}
	return x*f;
}
const int N=1e5+10,inf=1e17+7;
struct edge{int from,to,next,w,c;}e[N<<1];
int head[N],ecnt=-1,n,m,s,t,dis[N],flow[N],in[N],pre[N];
void add_edge(int u,int v,int w,int c){
	e[++ecnt].to=v;e[ecnt].from=u;
	e[ecnt].w=w;e[ecnt].c=c;
	e[ecnt].next=head[u];head[u]=ecnt;
}
queue<int> q;
int spfa(){
	memset(pre,-1,sizeof(pre));
	memset(dis,0x3f,sizeof(dis));
	memset(in,0,sizeof(in));
	q.push(s);in[s]=1;dis[s]=0;flow[s]=inf;
	while(!q.empty()){
		int u=q.front();q.pop();in[u]=0;
		for(int j=head[u];~j;j=e[j].next){
			int v=e[j].to,c=e[j].c,w=e[j].w;
			if(w>0 && dis[v]>dis[u]+c){
				dis[v]=dis[u]+c;pre[v]=j;
				flow[v]=min(flow[u],w);
				if(!in[v]) q.push(v),in[v]=1;
			}
		}
	}
	return pre[t]!=-1;
}
int solve(){
	int f=0,c=0;
	while(spfa()){
		int p=t;
		while(pre[p]!=-1){
			int j=pre[p];
			e[j].w-=flow[t];
			e[j^1].w+=flow[t];
			p=e[j].from;
		}
		f+=flow[t],c+=dis[t]*flow[t];
	}
	printf("%lld %lld",f,c);
}
signed main(){
	memset(head,-1,sizeof(head));
	n=read(),m=read(),s=read(),t=read();
	for(int i=1;i<=m;i++){
		int u=read(),v=read(),w=read(),c=read();
		add_edge(u,v,w,c);add_edge(v,u,0,-c);
	}
	solve();
	return 0;
}

回复

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

正在加载回复...