1/最大流

容量网络作为问题的有向图. 要有反向弧用于回流, 且反向弧容量为0.

残量网络, 残量=容量-当前流.(容量/当前流/残量都有反向弧) 残量>0,代表可达, 所以要不断在残量网络中找 s 到 t 的可达路. 称为增广路.

什么叫增广路? 就是当你把这条路加进来后, 会使你的结果更优. (在最大匹配中交错轨就是它的增广路).

找到增广路怎么更新当前流?

我们只需要维护一个 d[v] 值, 表示此次增广, 在残量网络上, s->v上的最小残量. 什么意思? 就是所组成的边的各个边权的最小值.

找到增广路后, 我们用 d[t] (t表示汇点), 来更新增广路上各边的流量(包括反向弧的), 然后把d[t]加进当前当前流结果即可.

当找不到增广路了, 当前流为最大流.

我们可以用bfs来找增广路. 这种最大流算法称为EK算法(也叫sap算法).

总结: 求最大流, 在于不断在残量网络上找各边残量>0的增广路, 用bfs来遍历残量网络, 维护d[v], 直到遍历到t.


2/最小费

容量网络各边增加一个费用权值(单位流量所需费用, 可以为负值).

要找出在最小费的前提下的最大流.

相较普通最大流, 我们不能再用bfs随意地遍历图了, 我们要优先选费用小的可行流. 

所以, 费用相当于残量网络的边权, 找增广路的过程变为在残量网络上找最短路. 残量网络中边的可达条件仍然是 残量>0.

在找到增广路(最短路)后, 我们再扫一遍这条路来计算各边最小残量, 为总流可改进量(等同于最大流里说的d[t]).

然后用最小残量来更新增广路上各边流量, 并把最小残量加进当前流结果.

同时更新最小费, 最小费 += 最小残量*最短路长.

总结: 跟普通最大流的区别就是遍历图时不能直接bfs, 而是找最短路(费用为权).