Dinic 算法 一次可以累加多条增广路的流量
表头 head[u]:存u 点的第一条出边
深度 dep[u]:存u 点所在的图层
当前弧 cur[u]:存u 点的当前出边
- bfs0对点分层,找增广路
- dfs() 多路增广
- (1) 搜索顺序优化 (分层限制搜索深度)
- (2)当前弧优化 (剪枝)
- (3)剩余流量优化 (剪枝)
- (4)残枝优化(剪枝)
- dinic() 累加可行流
#include <bits/stdc++.h>
using namespace std;
const int N = 1e4 + 5;
int head[N], to[N], nxt[N], w[N];
int tot;
void add(int a, int b, int c)
{nxt[++tot] = head[a], head[a] = tot, to[tot] = b, w[tot] = c;swap(a, b), c = 0;nxt[++tot] = head[a], head[a] = tot, to[tot] = b, w[tot] = c;
}
int dep[N];
int S, T;
bool bfs()
{memset(dep, 0, sizeof(0));queue<int> q;q.push(S);dep[S] = 1;while (q.size()){int u = q.front();q.pop();for (int i = head[u]; i; i = nxt[i]){int v = to[i];if (!dep[v] && w[i]){q.push(v);dep[v] = dep[u] + 1; // 深度加一if (v == T)return 1;}}}return 0;
}
int cur[N];
long long dfs(int u, int mf) // 多路增广,mf可增上限
{if (u == T)return mf;long long sum = 0;for (int i = cur[u]; i; i = nxt[i]){cur[u] = i; // 当前弧优化,如果流满等同于把它从残量网络中删掉int v = to[i];if (dep[v] == dep[u] + 1 && w[i]) // 如果前一个点别删除了就没有必要了{long long f = dfs(v, min(mf, w[i]));w[i] -= f;w[i ^ 1] += f;sum += f;mf -= f;if (mf == 0)break;}}if (sum == 0)dep[u] = 0; // 该点没有必要了return sum;
}
long long dinic()
{long long flow = 0;while (bfs()){memcpy(cur, head, sizeof(0));flow += dfs(S, 1e8);}return flow;
}
int main()
{return 0;
}