「学习笔记」费用流
费用流,和最大流的区别就是它的边权多了费用这个权值,一般是最小费用最大流,即在保证最大流的前提下做到费用最小
做法:贪心思想,按照费用来找出最短路,在所有的最短路上找增广路,直到没有增广路为止
ll spfa() {
for (int i = S; i <= T; ++ i) {
dis[i] = 1e18;
cur[i] = h[i];
}
deque<int> q;
q.push_back(S);
vis[S] = 1, dis[S] = 0;
while (!q.empty()) {
int u = q.front();
q.pop_front();
vis[u] = 0;
for (int i = h[u]; i; i = e[i].nxt) {
int v = e[i].v;
if (dis[v] > dis[u] + e[i].f && e[i].w) {
dis[v] = dis[u] + e[i].f;
if (!vis[v]) {
vis[v] = 1;
if (!q.empty() && dis[v] <= dis[q.front()]) {
q.push_front(v);
}
else {
q.push_back(v);
}
}
}
}
}
return dis[T] < 1e18;
}
ll dfs(int u, ll flow) {
if (u == T) {
return flow;
}
vis[u] = 1;
ll rest = flow, rlow = 0;
for (int &i = cur[u]; i && rest; i = e[i].nxt) {
int v = e[i].v;
if (dis[v] == dis[u] + e[i].f && !vis[v] && e[i].w) {
if ((rlow = dfs(v, min(rest, e[i].w)))) {
e[i].w -= rlow;
e[i ^ 1].w += rlow;
rest -= rlow;
cost += rlow * e[i].f;
}
}
}
vis[u] = 0;
return flow - rest;
}
while (spfa()) {
while (dfs(S, 1e18));
}
朝气蓬勃 后生可畏