最小费用最大流求调
查看原帖
最小费用最大流求调
178195
人间温柔楼主2023/1/23 20:57

这题很明显分为两部分,求最大流和最小费用。

目前已知,且能够保证求最大流的 dinicdinic 算法是绝对正确的,但是求醉小费用的时候我总是在 mincostmincost 函数中死循环,已经看了一整天了,找不出问题,求助大佬。

#include<bits/stdc++.h>
#include<unistd.h>
using namespace std;

const int maxn=5005;
const int maxm=50005;
const long long inf=1000000000000000000;

int n,m,s,t;
struct node{
	int fr,to,nxt;
	long long flow,flow1,cost;
}e[maxm<<1];
int cnt=1,head[maxn],dep[maxn],pre[maxn],vis[maxn],dis[maxn];
int q[maxn],l,r;

void add_edge(int u,int v,int flow,int flow1,int cost){
	cnt++;
	e[cnt].fr=u;
	e[cnt].to=v;
	e[cnt].nxt=head[u];
	e[cnt].flow=flow;
	e[cnt].flow1=flow1;
	e[cnt].cost=cost;
	head[u]=cnt;
}

bool bfs(){
	memset(dep,0,sizeof(dep));
	l=1; r=0;
	q[++r]=s;
	dep[s]=1;
	while(l<=r){
		int u=q[l];
		l++;
		for(int i=head[u];i;i=e[i].nxt){
			int v=e[i].to;
			if(dep[v]==0 && e[i].flow>0){
				dep[v]=dep[u]+1;
				q[++r]=v;
			}
		}
	}
	if(dep[t]==0) return false;
	else return true;
}

long long dfs(int u,long long flow){
	if(u==t){
		return flow;
	}
	long long tot=0;
	for(int i=head[u];i;i=e[i].nxt){
		int v=e[i].to;
		if(e[i].flow>0 && dep[v]==dep[u]+1){
			long long res=dfs(v,min(flow,e[i].flow));
			e[i].flow-=res;
			e[i^1].flow+=res;
			tot+=res;
			flow-=res;
			if(flow==0) break;
		}
	}
	if(tot==0) dep[u]=0;
	return tot;
}

long long dinic(){
	long long res=0;
	while(bfs()){
		res+=dfs(s,inf);
	}
	return res;
}

bool spfa(){
	memset(vis,0,sizeof(vis));
    memset(dis,0x3f,sizeof(dis));
    memset(pre,0,sizeof(pre));
    dis[s]=0;
    vis[s]=true;
    l=1; r=0;
    q[++r]=s;
    while(l<=r){
        int u=q[l];
        l++;
        vis[u]=false;
        for(int i=head[u];i;i=e[i].nxt){
            if(e[i].cost){
                int v=e[i].to;
                if(dis[u]+e[i].cost<dis[v]){
                    dis[v]=dis[u]+e[i].cost;
                    pre[v]=i;
                    if(!vis[v]){
                        q[++r]=v;
                        vis[v]=true;
                    }
                }
            }
        }
    }
    return pre[t]!=0;
}

long long mincost(){
	long long res=0;
	int i=1;
	while(cerr<<spfa()<<endl){
		cerr<<"done spfa"<<endl;
		long long flow=inf;
		for(int i=pre[t];i;i=pre[e[i^1].to]){
			flow=min(flow,e[i].flow1);
			cerr<<i<<" "<<e[i^1].to<<endl;
			sleep(1);
		}
		cerr<<"get out of the first for"<<endl;
		for(int i=pre[t];i;i=pre[e[i^1].to]){
			e[i].flow1-=flow;
			e[i^1].flow1+=flow;
			res+=e[i].cost*flow;
		}
		cerr<<"get out of the second for"<<endl;
		cerr<<"done round "<<i<<endl;
		i++;
	}
	return res;
}

int main(){
	cin>>n>>m>>s>>t;
	for(int i=1;i<=m;i++){
		int u,v,flow,cost;
		cin>>u>>v>>flow>>cost;
		add_edge(u,v,flow,flow,cost);
		add_edge(v,u,0,0,-cost);
	}
	cout<<dinic()<<" ";
	cout<<mincost()<<endl;
	return 0;
}
2023/1/23 20:57
加载中...