最小费用最大流EK
前言
模板题:P3381 【模板】最小费用最大流
费用流题单
前置知识:最大流Dinic
进阶知识:最小费用最大流Dinic
最小费用最大流问题,简称费用流。费用流问题是在最大流的基础上给每条边添加一个边权,也就是费用,总费用就是流过每条边的流量乘上费用的和,在保证流量最大的情况下,求出这个最小费用。
最大流问题可以使用每次 dfs 找增广路来解决,费用流就可以用 SPFA 来寻找增广路,这样就可以保证每一次的增广路的费用最小。由于最大流算法可以“反悔”,所以即使当前的增广路并不是全局最优的,也可以在之后的增广中“反悔”,所以最后找到的一定是最优解。不过 SPFA 在搜索过程中不知道最优解,所以要记录最优路线,搜索完成后再更新所有边的容量。
SPFA
SPFA 的过程中总共需要维护 $3$ 个数组:到达每个点的流量,到达每个点的费用,与这个点是由哪个点更新来的。不过SPFA是找到费用最小的增广路,而不是流量最大,因为可以进行多次 SPFA 增加流量。如果当前边的流量不为 $0$ ,到达每个点的最小费用 $g$ 的就可以做如下更新: $g[a[i].m]=\max(g[a[i].m],g[x]))$。如果最小费用更新成功,流量 $f[a[i].m]$ 也要更新为 $min(f[x]),a[i].r$ ,这个点的父亲 $r[a[i].m]$ 则更新为 $x$。这样就可以找到当前费用最小的增广路。当汇点没有被走到的时候,就说明不存在增广路了。
进行完一次 SPFA 后,最大流量就要加上汇点的流量 $f[t]$,费用加上汇点的流量与到达汇点的费用之积 $f[t] \times g[t]$
在进行了 SPFA 之后,我们就需要更新每条边的容量。从汇点开始,每一次都到达当前点的父亲,并把经过的所有边的容量减去 $f[t]$,其相反边的容量加上 $f[s]$。
code
1 |
|