网络流-费用流

定义

给定一个有 \(n\) 个点 \(m\) 条边的网络,每条边有一个容量限制 \(C_{x\to y}\) 和一个使用的代价 \(w_{x\to y}\)。当边 \(x\to y\) 使用的流量为 \(f_{x\to y}\) 时,其花费的代价为 \(w_{x\to y}\times f_{x\to y}\)。这个网络中总共代价最少的最大流被称为最小费用最大流,总共代价最多的最大流被称为最大费用最大流。

注意:费用流是建立在最大流的基础上的,让流量的大小是第一关键字。

求解

因为最大流是一样的,所以依然可以套用 Dinic 的思路。因为 Dinic 的增广路长度是可以贪心的寻找的,所以只要每一次增广路的费用最小,那么就可以让费用最小。所以我们可以将将代价看作边权,把原本的 bfs 换成 spfa 找最短路。

如果需要求解费用最大最大流,那么只需要将所有的边取反,再跑一次费用最小最大流就可以了。

实现

#include<iostream>
#include<cstring>
#include<vector>
#include<queue>
#define int long long
using namespace std;
const int N=1e6,inf=0x3f3f3f3f3f3f3f3f;
struct node{int x,v,w,id;};
vector<node> v[N];
void add(int x,int y,int val,int w){
    int sti=v[x].size(),edi=v[y].size();
    v[x].push_back({y,val,w,edi});
    v[y].push_back({x,0,-w,sti});
}
int n,m,s,t,dep[N],p[N],sum;
bool vis[N];
bool bfs(){
	memset(dep,0x3f,sizeof(dep));
	memset(p,0,sizeof(p));
    memset(vis,0,sizeof(vis));
	queue<int> q;
	q.push(s);
	vis[s]=1,dep[s]=1;
	while(!q.empty()){
		int x=q.front();q.pop();
		vis[x]=0;
		for(node i:v[x]){
			if(i.v&&dep[x]+i.w<dep[i.x]){
				dep[i.x]=dep[x]+i.w;
				if(!vis[i.x]){
                    vis[i.x]=1;
                    q.push(i.x);
                }
			}
		}
	}
	return dep[t]!=inf;
}
int dfs(int x,int flow){
    if(x==t){
        return flow;
    }
    vis[x]=1;
    for(int i=p[x];i<v[x].size();i++){
        p[x]=i;
        int to=v[x][i].x,len=v[x][i].v;
        if(!vis[to]&&dep[x]+v[x][i].w==dep[to]&&len){
            int t=dfs(to,min(len,flow));
            if(t){
                v[x][i].v-=t;
                v[to][v[x][i].id].v+=t;
                sum+=t*v[x][i].w;
                return t;
            }
            else{
                dep[to]=-1;
            }
        }
    }
    vis[x]=0;
    return 0;
}
int dinic(){
    int ans=0;
    while(bfs()){
        ans+=dfs(s,inf);
    }
    return ans;
}
signed main(){
    cin>>n>>m>>s>>t;
    for(int i=1,x,y,val,w;i<=m;i++){
        cin>>x>>y>>val>>w;
        add(x,y,val,w);
    }
    cout<<dinic()<<' '<<sum<<'\n';
    return 0;
}
posted @ 2024-07-12 13:17  未抑郁的刘大狗  阅读(9)  评论(0编辑  收藏  举报