费用流建双向边的反向边时费用没取负A了?!
查看原帖
费用流建双向边的反向边时费用没取负A了?!
556362
Unnamed114514楼主2023/7/20 15:07
#include<bits/stdc++.h>
#define inf 0x3f3f3f3f
#define add(u,v,w,C) add_edge(u,v,w,C),add_edge(v,u,0,C)
using namespace std;
const int N=1e4+5,M=2e4+5;
int n,m,k,S,s,t,ans1,ans2,tot,u[M],v[M],C[M],a[N],dis[N],head[N],nxt[M],to[M],c[M],cost[M],delta;
bool vis[N];
inline void add_edge(int u,int v,int w,int C){
	++tot,nxt[tot]=head[u],head[u]=tot,to[tot]=v,c[tot]=w,cost[tot]=C;
}
queue<int> q;
inline bool SPFA(int s){
	memset(dis,inf,sizeof(dis));
	memset(vis,0,sizeof(vis));
	while(q.size()) q.pop();
	q.push(s),dis[s]=0,vis[s]=1;
	while(q.size()){
		int u=q.front();
		q.pop();
		vis[u]=0;
		for(int H=head[u];~H;H=nxt[H]){
			int v=to[H],w=c[H],C=cost[H];
			if(w&&dis[u]+C<dis[v]){
				dis[v]=dis[u]+C;
				if(!vis[v]){
					vis[v]=1;
					q.push(v);
				}
			}
		}
	}
	if(dis[t]==inf)
		return 0;
	else
		return 1;
}
int dfs(int u,int F){
	if(u==t)
		return F;
	vis[u]=1;
	int rest=F;
	for(int H=head[u];~H;H=nxt[H]){
		int v=to[H],w=c[H],C=cost[H];
		if(!vis[v]&&w>0&&dis[v]==dis[u]+C){
			int Delta=dfs(v,min(w,rest));
			if(!Delta)
				dis[v]=inf;
			ans2+=Delta*C;
			c[H]-=Delta,c[H^1]+=Delta;
			rest-=Delta;
		}
	}
	vis[u]=0;
	return F-rest;
}
inline void dinic(){
	while(SPFA(s))
		ans1+=dfs(s,inf);
}
int main(){
	memset(head,-1,sizeof(head)),tot=1;
	scanf("%d%d%d",&n,&m,&k);
	for(int i=1,w;i<=m;++i){
		scanf("%d%d%d%d",&u[i],&v[i],&w,&C[i]);
		add(u[i],v[i],w,0);
	}
	s=1,t=n;
	dinic();
	printf("%d ",ans1);
	for(int i=1;i<=m;++i)
		add(u[i],v[i],inf,C[i]);
	add(t,n+1,k,0);
	t=n+1;
	dinic();
	printf("%d\n",ans2);
	return 0;
}
2023/7/20 15:07
加载中...