求助一个问题
  • 板块学术版
  • 楼主Kniqht
  • 当前回复0
  • 已保存回复0
  • 发布时间2023/12/15 18:57
  • 上次更新2023/12/15 20:48:28
查看原帖
求助一个问题
315205
Kniqht楼主2023/12/15 18:57

有源汇上下界最小流

先求出可行流,然后求出 T->S 的最大流,减一下得出最小流

但是样例

7 12 6 7
6 1 0 2147483647
1 7 0 2147483647
6 2 0 2147483647
2 7 0 2147483647
6 3 0 2147483647
3 7 0 2147483647
6 4 0 2147483647
4 7 0 2147483647
6 5 0 2147483647
5 7 0 2147483647
5 1 1 2147483647
3 4 1 2147483647
Output: 2
My output: -99999999999998

然后我输出 inf+ans 就对了,我设的 inf 是1e14 为啥呢?题目:link

#include<bits/stdc++.h>
#define int long long
using namespace std;
const int N=2e5+10,M=1e6+10,inf=1e14; 
int n,m,s,t;
int h[N],e[M*2],ne[M*2],w[M*2],idx;
void add(int a,int b,int c){
	e[idx]=b,ne[idx]=h[a],w[idx]=c,h[a]=idx++;
} 
int maxflow,cur[N],d[N];
bool bfs(){
	for(int i=0;i<=n+1;i++) d[i]=inf;
	queue<int> q;q.push(s);
	d[s]=0;cur[s]=h[s];
	while(!q.empty()){
		int x=q.front();q.pop();
		for(int i=h[x];~i;i=ne[i]){
			int j=e[i];
			if(w[i]>0&&d[j]==inf){
				q.push(j);
				d[j]=d[x]+1;
				cur[j]=h[j];
				if(j==t) return 1;
			}
		}
	} 
	return 0;
}
int dinic(int x,int flow){
	if(x==t) return flow;
	int res=0,k;
	for(int i=cur[x];~i&&flow;i=ne[i]){
		cur[x]=i; 
		int j=e[i];
		if(w[i]>0&&d[j]==d[x]+1){
			k=dinic(j,min(flow,w[i]));
			if(!k) d[j]=inf;
			w[i]-=k;w[i^1]+=k;
			res+=k;flow-=k;
		}
	}
	return res;
}
int a[N],low[M],S,T;
signed main(){
	memset(h,-1,sizeof(h)); 
    scanf("%lld%lld%lld%lld",&n,&m,&S,&T);
    int u,v,l,r;s=0,t=n+1;
    for(int i=1;i<=m;i++){
    	scanf("%lld%lld%lld%lld",&u,&v,&l,&r);
    	low[i]=l; 
    	add(u,v,r-l);add(v,u,0);
    	a[u]-=l,a[v]+=l;
	}
	int sum=0;
	for(int i=1;i<=n;i++){
		if(a[i]>0) sum+=a[i],add(s,i,a[i]),add(i,s,0);
		else if(a[i]<0) add(i,t,-a[i]),add(t,i,0);
	}
	add(T,S,inf);add(S,T,0);
	int maxflow=0;
	while(bfs()) maxflow+=dinic(s,inf);
	if(maxflow<sum){
		printf("No Solution");
		return 0;
	}
	maxflow=w[idx];
	w[idx]=w[idx-1]=0;
	s=T,t=S;
	while(bfs()) maxflow-=dinic(s,inf);
	printf("%lld",inf+maxflow); 
	return 0;
}
2023/12/15 18:57
加载中...