Loading docs/graph/flow/max-flow.md +199 −242 Original line number Diff line number Diff line Loading @@ -46,13 +46,7 @@ EK 算法的时间复杂度为 $O(n^2m)$ (其中 $n$ 为点数, $m$ 为边 struct Edge { int from, to, cap, flow; Edge(int u, int v, int c, int f) : from(u) , to(v) , cap(c) , flow(f) { } Edge(int u, int v, int c, int f) : from(u), to(v), cap(c), flow(f) {} }; struct EK { Loading @@ -61,15 +55,12 @@ struct EK { vector<int> G[maxn]; int a[maxn], p[maxn]; void init(int n) { for (int i = 0; i < n; i++) G[i].clear(); void init(int n) { for (int i = 0; i < n; i++) G[i].clear(); edges.clear(); } void AddEdge(int from, int to, int cap) { void AddEdge(int from, int to, int cap) { edges.push_back(Edge(from, to, cap, 0)); edges.push_back(Edge(to, from, 0, 0)); m = edges.size(); Loading @@ -77,8 +68,7 @@ struct EK { G[to].push_back(m - 1); } int Maxflow(int s, int t) { int Maxflow(int s, int t) { int flow = 0; for (;;) { memset(a, 0, sizeof(a)); Loading @@ -96,11 +86,9 @@ struct EK { Q.push(e.to); } } if (a[t]) break; if (a[t]) break; } if (!a[t]) break; 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]; Loading Loading @@ -140,13 +128,7 @@ Dinic 算法有两个优化: struct Edge { int from, to, cap, flow; Edge(int u, int v, int c, int f) : from(u) , to(v) , cap(c) , flow(f) { } Edge(int u, int v, int c, int f) : from(u), to(v), cap(c), flow(f) {} }; struct Dinic { Loading @@ -156,15 +138,12 @@ struct Dinic { int d[maxn], cur[maxn]; bool vis[maxn]; void init(int n) { for (int i = 0; i < n; i++) G[i].clear(); void init(int n) { for (int i = 0; i < n; i++) G[i].clear(); edges.clear(); } void AddEdge(int from, int to, int cap) { void AddEdge(int from, int to, int cap) { edges.push_back(Edge(from, to, cap, 0)); edges.push_back(Edge(to, from, 0, 0)); m = edges.size(); Loading @@ -172,8 +151,7 @@ struct Dinic { G[to].push_back(m - 1); } bool BFS() { bool BFS() { memset(vis, 0, sizeof(vis)); queue<int> Q; Q.push(s); Loading @@ -194,10 +172,8 @@ struct Dinic { return vis[t]; } int DFS(int x, int a) { if (x == t || a == 0) return a; int DFS(int x, int a) { if (x == t || a == 0) return a; int flow = 0, f; for (int& i = cur[x]; i < G[x].size(); i++) { Edge& e = edges[G[x][i]]; Loading @@ -206,15 +182,13 @@ struct Dinic { edges[G[x][i] ^ 1].flow -= f; flow += f; a -= f; if (a == 0) break; if (a == 0) break; } } return flow; } int Maxflow(int s, int t) { int Maxflow(int s, int t) { this->s = s; this->t = t; int flow = 0; Loading @@ -234,17 +208,10 @@ struct Dinic { ```cpp struct Edge { int from, to, cap, flow; Edge(int u, int v, int c, int f) : from(u) , to(v) , cap(c) , flow(f) { } Edge(int u, int v, int c, int f) : from(u), to(v), cap(c), flow(f) {} }; bool operator<(const Edge& a, const Edge& b) { bool operator<(const Edge& a, const Edge& b) { return a.from < b.from || (a.from == b.from && a.to < b.to); } Loading @@ -258,8 +225,7 @@ struct ISAP { int p[maxn]; int num[maxn]; void AddEdge(int from, int to, int cap) { void AddEdge(int from, int to, int cap) { edges.push_back(Edge(from, to, cap, 0)); edges.push_back(Edge(to, from, 0, 0)); m = edges.size(); Loading @@ -267,8 +233,7 @@ struct ISAP { G[to].push_back(m - 1); } bool BFS() { bool BFS() { memset(vis, 0, sizeof(vis)); queue<int> Q; Q.push(t); Loading @@ -289,16 +254,13 @@ struct ISAP { return vis[s]; } void init(int n) { void init(int n) { this->n = n; for (int i = 0; i < n; i++) G[i].clear(); for (int i = 0; i < n; i++) G[i].clear(); edges.clear(); } int Augment() { int Augment() { int x = t, a = INF; while (x != s) { Edge& e = edges[p[x]]; Loading @@ -314,15 +276,13 @@ struct ISAP { return a; } int Maxflow(int s, int t) { int Maxflow(int s, int t) { this->s = s; this->t = t; int flow = 0; BFS(); memset(num, 0, sizeof(num)); for (int i = 0; i < n; i++) num[d[i]]++; for (int i = 0; i < n; i++) num[d[i]]++; int x = s; memset(cur, 0, sizeof(cur)); while (d[s] < n) { Loading @@ -345,15 +305,12 @@ struct ISAP { int m = n - 1; for (int i = 0; i < G[x].size(); i++) { Edge& e = edges[G[x][i]]; if (e.cap > e.flow) m = min(m, d[e.to]); if (e.cap > e.flow) m = min(m, d[e.to]); } if (--num[d[x]] == 0) break; if (--num[d[x]] == 0) break; num[d[x] = m + 1]++; cur[x] = 0; if (x != s) x = edges[p[x]].from; if (x != s) x = edges[p[x]].from; } } return flow; Loading Loading
docs/graph/flow/max-flow.md +199 −242 Original line number Diff line number Diff line Loading @@ -46,13 +46,7 @@ EK 算法的时间复杂度为 $O(n^2m)$ (其中 $n$ 为点数, $m$ 为边 struct Edge { int from, to, cap, flow; Edge(int u, int v, int c, int f) : from(u) , to(v) , cap(c) , flow(f) { } Edge(int u, int v, int c, int f) : from(u), to(v), cap(c), flow(f) {} }; struct EK { Loading @@ -61,15 +55,12 @@ struct EK { vector<int> G[maxn]; int a[maxn], p[maxn]; void init(int n) { for (int i = 0; i < n; i++) G[i].clear(); void init(int n) { for (int i = 0; i < n; i++) G[i].clear(); edges.clear(); } void AddEdge(int from, int to, int cap) { void AddEdge(int from, int to, int cap) { edges.push_back(Edge(from, to, cap, 0)); edges.push_back(Edge(to, from, 0, 0)); m = edges.size(); Loading @@ -77,8 +68,7 @@ struct EK { G[to].push_back(m - 1); } int Maxflow(int s, int t) { int Maxflow(int s, int t) { int flow = 0; for (;;) { memset(a, 0, sizeof(a)); Loading @@ -96,11 +86,9 @@ struct EK { Q.push(e.to); } } if (a[t]) break; if (a[t]) break; } if (!a[t]) break; 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]; Loading Loading @@ -140,13 +128,7 @@ Dinic 算法有两个优化: struct Edge { int from, to, cap, flow; Edge(int u, int v, int c, int f) : from(u) , to(v) , cap(c) , flow(f) { } Edge(int u, int v, int c, int f) : from(u), to(v), cap(c), flow(f) {} }; struct Dinic { Loading @@ -156,15 +138,12 @@ struct Dinic { int d[maxn], cur[maxn]; bool vis[maxn]; void init(int n) { for (int i = 0; i < n; i++) G[i].clear(); void init(int n) { for (int i = 0; i < n; i++) G[i].clear(); edges.clear(); } void AddEdge(int from, int to, int cap) { void AddEdge(int from, int to, int cap) { edges.push_back(Edge(from, to, cap, 0)); edges.push_back(Edge(to, from, 0, 0)); m = edges.size(); Loading @@ -172,8 +151,7 @@ struct Dinic { G[to].push_back(m - 1); } bool BFS() { bool BFS() { memset(vis, 0, sizeof(vis)); queue<int> Q; Q.push(s); Loading @@ -194,10 +172,8 @@ struct Dinic { return vis[t]; } int DFS(int x, int a) { if (x == t || a == 0) return a; int DFS(int x, int a) { if (x == t || a == 0) return a; int flow = 0, f; for (int& i = cur[x]; i < G[x].size(); i++) { Edge& e = edges[G[x][i]]; Loading @@ -206,15 +182,13 @@ struct Dinic { edges[G[x][i] ^ 1].flow -= f; flow += f; a -= f; if (a == 0) break; if (a == 0) break; } } return flow; } int Maxflow(int s, int t) { int Maxflow(int s, int t) { this->s = s; this->t = t; int flow = 0; Loading @@ -234,17 +208,10 @@ struct Dinic { ```cpp struct Edge { int from, to, cap, flow; Edge(int u, int v, int c, int f) : from(u) , to(v) , cap(c) , flow(f) { } Edge(int u, int v, int c, int f) : from(u), to(v), cap(c), flow(f) {} }; bool operator<(const Edge& a, const Edge& b) { bool operator<(const Edge& a, const Edge& b) { return a.from < b.from || (a.from == b.from && a.to < b.to); } Loading @@ -258,8 +225,7 @@ struct ISAP { int p[maxn]; int num[maxn]; void AddEdge(int from, int to, int cap) { void AddEdge(int from, int to, int cap) { edges.push_back(Edge(from, to, cap, 0)); edges.push_back(Edge(to, from, 0, 0)); m = edges.size(); Loading @@ -267,8 +233,7 @@ struct ISAP { G[to].push_back(m - 1); } bool BFS() { bool BFS() { memset(vis, 0, sizeof(vis)); queue<int> Q; Q.push(t); Loading @@ -289,16 +254,13 @@ struct ISAP { return vis[s]; } void init(int n) { void init(int n) { this->n = n; for (int i = 0; i < n; i++) G[i].clear(); for (int i = 0; i < n; i++) G[i].clear(); edges.clear(); } int Augment() { int Augment() { int x = t, a = INF; while (x != s) { Edge& e = edges[p[x]]; Loading @@ -314,15 +276,13 @@ struct ISAP { return a; } int Maxflow(int s, int t) { int Maxflow(int s, int t) { this->s = s; this->t = t; int flow = 0; BFS(); memset(num, 0, sizeof(num)); for (int i = 0; i < n; i++) num[d[i]]++; for (int i = 0; i < n; i++) num[d[i]]++; int x = s; memset(cur, 0, sizeof(cur)); while (d[s] < n) { Loading @@ -345,15 +305,12 @@ struct ISAP { int m = n - 1; for (int i = 0; i < G[x].size(); i++) { Edge& e = edges[G[x][i]]; if (e.cap > e.flow) m = min(m, d[e.to]); if (e.cap > e.flow) m = min(m, d[e.to]); } if (--num[d[x]] == 0) break; if (--num[d[x]] == 0) break; num[d[x] = m + 1]++; cur[x] = 0; if (x != s) x = edges[p[x]].from; if (x != s) x = edges[p[x]].from; } } return flow; Loading