Continuation of this blog Last Blog (Maximum Stream Dinic algorithm), this time the EK algorithm is used to solve the maximum flow problem.
EK algorithm idea: Search for an extension road from source to sink in the graph, you need to record this path, increase the maximum feasible flow Liu of this path to result ans, then update the weight of each edge on the path from sink to source (minus this liu), and update the weight of the opposite edge (plus this liu).Then search for a new extension..., loop until no new expansion path is found, and then the ANS is the maximum flow.
Note: When EK solves the maximum flow, I see that others use a matrix to build the graph, so when updating the edge weights on the extended path in reverse, only the father nodes of each point need to be recorded before.I modified the EK algorithm on the previous DIIC's forward star code. The connection's side numbers cannot be directly derived from the father's and child's node numbers, so an additional variable, edgeIndex[v], is needed to record the side numbers from u to v, which makes it easy to reverse modify the side weights.
The code is as follows:
#include <iostream> #include <algorithm> #include <cstring> #include <cstdio> #include <cstdlib> #include <queue> using namespace std; const int N = 105; const int MAXN = 0x3fffffff; struct Edge { int to; int value; int next; }e[2 * N*N]; int head[N], cnt; int p[N], fa[N], edgeIndex[N]; int n, np, nc, m; void insert(int u, int v, int value) { e[++cnt].to = v; e[cnt].value = value; e[cnt].next = head[u]; head[u] = cnt; } void init() { memset(head, -1, sizeof(head)); cnt = -1; } int BFS() { int ans = 0; while (1) { memset(p, -1, sizeof(p)); queue<int> Q; Q.push(0); p[0] = MAXN; while (!Q.empty()) { int u = Q.front(); Q.pop(); for (int edge = head[u]; edge != -1; edge = e[edge].next) { int v = e[edge].to; if (p[v] ==-1 && e[edge].value > 0) { p[v] = min(p[u], e[edge].value); fa[v] = u; edgeIndex[v] = edge; Q.push(v); if (v == n + 1) goto endw; } } } endw:; if (p[n+1] == -1) return ans; else { ans += p[n + 1]; int x = n + 1; while (x) { int edge = edgeIndex[x]; e[edge].value -= p[n + 1]; e[edge ^ 1].value += p[n + 1]; x = fa[x]; } } } } int main() { while (scanf("%d%d%d%d", &n, &np, &nc, &m) != EOF) { init(); int u, v, z; for (int i = 0; i < m; i++) { scanf(" (%d,%d)%d", &u, &v, &z); insert(u + 1, v + 1, z); insert(v + 1, u + 1, 0); } for (int i = 0; i < np; i++) { scanf(" (%d)%d", &u, &z); insert(0, u + 1, z); insert(u + 1, 0, 0); } for (int i = 0; i < nc; i++) { scanf(" (%d)%d", &u, &z); insert(u + 1, n + 1, z); insert(n + 1, u + 1, 0); } printf("%d\n", BFS()); } }