};
struct EK {
- int n, m;
- vector<Edge> edges;
- vector<int> G[maxn];
- int a[maxn], p[maxn];
+ int n, m; // n:点数,m:边数
+ vector<Edge> edges; // edges:所有边的集合
+ vector<int> G[maxn]; // G:点 x -> x 的所有边在 edges 中的下标
+ int a[maxn], p[maxn]; // a:点 x -> BFS 过程中最近接近点 x 的边给它的最大流
+ // p:点 x -> BFS 过程中最近接近点 x 的边
void init(int n) {
for (int i = 0; i < n; i++) G[i].clear();
while (!Q.empty()) {
int x = Q.front();
Q.pop();
- for (int i = 0; i < G[x].size(); i++) {
+ for (int i = 0; i < G[x].size(); i++) { // 遍历以 x 作为起点的边
Edge& e = edges[G[x][i]];
if (!a[e.to] && e.cap > e.flow) {
- p[e.to] = G[x][i];
- a[e.to] = min(a[x], e.cap - e.flow);
+ p[e.to] = G[x][i]; // G[x][i] 是最近接近点 e.to 的边
+ a[e.to] = min(a[x], e.cap - e.flow); // 最近接近点 e.to 的边赋给它的流
Q.push(e.to);
}
}
- if (a[t]) break;
+ if (a[t]) break; // 如果汇点接受到了流,就退出 BFS
}
- if (!a[t]) break;
- for (int u = t; u != s; u = edges[p[u]].from) {
- edges[p[u]].flow += a[t];
- edges[p[u] ^ 1].flow -= a[t];
+ if (!a[t]) break; // 如果汇点没有接受到流,说明源点和汇点不在同一个连通分量上
+ for (int u = t; u != s; u = edges[p[u]].from) { // 通过 u 追寻 BFS 过程中 s -> t 的路径
+ edges[p[u]].flow += a[t]; // 增加路径上边的 flow 值
+ edges[p[u] ^ 1].flow -= a[t]; // 减小反向路径的 flow 值
}
flow += a[t];
}