
根据网络流相关的知识,可以以计算机为顶点,通信电缆为边,从而得到一个有向图,每条边 e e e都有容量 c ( e ) c(e) c(e)和费用 d ( e ) d(e) d(e)。题目可以理解为,保证从 s s s到 t t t有流量为 F F F的流的前提下,使得费用 ∑ e ( f ( e ) ∗ d ( e ) ) \sum_e(f(e)*d(e)) ∑e(f(e)∗d(e))最小。
这就是在最大流问题的网络中,给边新加上了费用,而求的不再是流量的最大值,而是流量为F 时费用的最小值。这类问题叫做最小费用流问题。
接下来,让我们来考虑一下这类问题的解法。求解最大流时,我们在残余网络上不断贪心地增广而得到了最大流。现在边上多了费用,如果我们在残余网络上总是沿着最短路增广又如何呢?此时,残余网络中的反向边的费用应该是原边费用的相反数,以保证过程是可逆而正确的。为什么?如果让我们来设置反向边的费用又该如何设计?首先我们原边与反向边的花费数值上一定要保持一致,毕竟本质上是一条路,正反走应该都差不多。那么直接让二者相等吗?要知道,反向弧设计的初衷,是给我们的算法提供一个后悔的机会反向弧理解,而最小费用流的后悔要如何理解?我们先按照花费相等建立一个残余网络:

假设我们第一次走了1-2-5-6,然后建立了该残余网络,此时到2,5,6的花费分别为0+5*10,5*10+5*10,5*10+5*10+5*10,如果我们要用这个反悔的机会,那么在把2->5的流量退回2时,就有如下更新cost[2]=cost[5]+10*5???显然和我们的意图不太一样,我们需要令2的花费保持原状,如果此时的花费是-5呢?那么我们有cost[2]=cost[5]-5*10,流量成功退回而且花费也保持在原状。
因为有了负权边,所以就不能用 Dijkstra算法求最短路了,而需要用Bellman-Ford算法。



tips:以下是最小费用最大流的代码,固定流的话其实差别不大。我们只需要不断的更新最大流,直到他超过了预期的流量。
#include<bits/stdc++.h>
using <

本文深入探讨了最小费用流问题,介绍了如何在网络流问题的基础上,通过添加边费用,求解在保证特定流量下费用最小的路径。文章详细解释了算法原理,包括反向边费用的设计及其在残余网络中的作用,并提供了具体的实现代码。
最低0.47元/天 解锁文章
1万+

被折叠的 条评论
为什么被折叠?



