网络流之费用流

求费用流目前好像只有EK+SPFA改版,时间复杂度为O(N*E*k),其中K为最大流值。但时间上的期望时间复杂度为:O(A*E*K),其中A为所有顶点进队列的平均次数,可以证明A一般小于等于2。


最小费用最大流:

#include <bits/stdc++.h>
using namespace std;
const int inf = 0x3f3f3f3f;
const int maxn = 205;
struct node
{
	int v, to, w, cost, next;
}edge[maxn*maxn];
int no, n, m, s, t;
int head[maxn], dis[maxn], vis[maxn], pre[maxn], rec[maxn];
queue<int> q;
inline void init()
{
	no = 0;
	memset(head, -1, sizeof head);
}
inline void add(int u, int v, int w, int f)
{
	edge[no].v = v; edge[no].w = w; edge[no].cost = f;
	edge[no].next = head[u]; head[u] = no++;
	edge[no].v = u; edge[no].w = 0; edge[no].cost = -f;
	edge[no].next = head[v]; head[v] = no++;
}
int SPFA(int s, int t)
{
	memset(dis, 0x3f, sizeof dis);
	memset(vis, 0, sizeof vis);
	while(!q.empty()) q.pop();
	q.push(s); dis[s] = 0; vis[s] = 1;
	while(!q.empty())
	{
		int tp = q.front(); q.pop();
		vis[tp] = 0;
		int k = head[tp];
		while(k != -1)
		{
			if(dis[edge[k].v] > dis[tp] + edge[k].cost && edge[k].w)
			{
				dis[edge[k].v] = dis[tp] + edge[k].cost;
				pre[edge[k].v] = tp; rec[edge[k].v] = k;
				if(vis[edge[k].v] == 0)
				{
					vis[edge[k].v] = 1;
					q.push(edge[k].v);
				}
			}
			k = edge[k].next;
		}
	}
	if(dis[t] == inf) return 0;
	return 1;
}
pair<int, int> Mcmf(int s, int t)
{
	int minflow, k, mincost = 0, maxflow = 0;
	while(SPFA(s, t))
	{
		k = t; minflow = inf;
		while(k != s)
		{
			minflow = min(minflow, edge[rec[k]].w);
			k = pre[k];
		}
		k = t; maxflow += minflow;
		while(k != s)
		{
			mincost += minflow*edge[rec[k]].cost;
			edge[rec[k]].w -= minflow;
			edge[rec[k]^1].w += minflow;
			k = pre[k];
		}
	}
	return make_pair(maxflow, mincost);
}
int main()
{
	int u, v, w, f;
	scanf("%d %d %d %d", &n, &m, &s, &t);
	init();
	for(int i = 1; i <= m; ++i)
	{
		scanf("%d %d %d %d", &u, &v, &w, &f);
		add(u, v, w, f);
	}
	pair<int, int> ans = Mcmf(s, t);
	cout << ans.first << " " << ans.second << endl;
	return 0;
}

有时候也会遇到最大费用最大流,其实只要在建图时将所有费用取负,最后求的最小费用取负就是最大费用。


最小费用最大流是指满足源点流出的流量最大时,总费用最小的一个网络,模板都是基于此。

最大费用最大流则是将所有的费用取负,然后再跑一遍最小费用最大流,将最终的最小费用取负就是最大流量下的最大费用了。

最大费用可行流关注的是费用而非流量是否最大,那么当我们在寻找可改进路时如果从源点到汇点的dis变成大于0的时侯,则表明可改进路不会再减少费用了,所以在SPFA寻找增广路时return的条件改为dis[t] <= 0即可。

最小费用可行流没有意义。


继续加油~

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值