概念:
在同一个网络中,可能存在多个总流量相同的最大流,我们可以在计算流量的基础之上,给网络中的弧增加一个单位流量的费用(简称费用),在确保流量最大的前提下总费用最小——最小费用最大流。
算法思路:
边权的数据有两个,一个是容量,一个是费用。
主要是两部分,①spfa来求边权(根据费用w)最短路;②在最短路基础上统计计算最小费用的。用spfa求出最短路(其中有个pre[i]数组表示指向i点的边序号),然后再倒序从终点沿着最短路走反向边,找到该最短路上的最小边权——流量。然后再来走一遍,这次需要每次都把最小费用统计一下(+=最小流量*费用),同时从当前边权容量上减去当前流量,以便进入下一次循环的spfa。
const int MAX_N = 1000;
const int MAX_M = 10000;
const int inf = 0x3f3f3f3f;
struct edge {
int v, c, w, next; // v 表示边的另一个顶点,c 表示当前剩余容量,w 表示单位流量费用
} e[MAX_M];
int p[MAX_N], s, t, eid; // s 表示源点,t 表示汇点,需要在进行 costflow 之前设置完毕
void init() {
memset(p, -1, sizeof(p));
eid = 0;
}
void insert(int u, int v, int c, int w) {
e[eid].v = v;
e[eid].c = c;
e[eid].w = w;
e[eid].next = p[u];
p[u] = eid++;
}
void addedge(int u, int v,