Ek complexity O (V * E)
# Define n 204 int C [N] [N]; // edge capacity int f [N] [N]; // actual edge traffic int pre [N]; // record the augmented path int res [N]; // residual network queue <int> QQ; void Init () {While (! QQ. empty () QQ. pop (); memset (C, 0, sizeof (c); memset (F, 0, sizeof (f);} int EK (int s, int T) {int I, j; int ans = 0; while (1) {memset (Res, 0, sizeof (RES); Res [s] = max; // The residual network of the source point must be set to infinitely large! Otherwise pre [s] =-1; QQ. Push (s); // BFS find the augmented path while (! QQ. empty () {int x = QQ. front (); QQ. pop (); for (I = 1; I <= T; I ++) {If (! Res [I] & F [x] [I] <C [x] [I]) {QQ. push (I); Pre [I] = x; Res [I] = min (C [x] [I]-f [x] [I], res [x]); // This is similar to DP. If there is an augmented path, then res [T] is the minimum permission of the augmented path }}if (RES [T] = 0) break; // exit int K = T if no augmented path is found; while (pre [k]! =-1) {f [pre [k] [k] + = res [T]; // Add new traffic to the forward edge f [k] [pre [k]-= res [T]; // The Reverse edge must subtract the new traffic, the reverse edge is used to give the program a chance to regret K = pre [k];} ans + = res [T];} return ans ;}
Dinic recursion (recommended)
# Define m 400 struct node {int U, V, next, cap;} edge [M * m]; int next [m], head [m], layer [m], Q [M * 2], Mark [m]; int ecnt; void Init () {ecnt = 0; memset (Head,-1, sizeof (head ));} void add (int u, int V, int c) {edge [ecnt]. U = u; edge [ecnt]. V = V; edge [ecnt]. CAP = C; edge [ecnt]. next = head [u]; head [u] = ecnt ++; edge [ecnt]. U = V; edge [ecnt]. V = u; edge [ecnt]. CAP = 0; edge [ecnt]. next = head [v]; head [v] = Ecnt ++;} bool BFS (INT begin, int end) {int I, L, H, K, Y; for (I = 0; I <= end; I ++) layer [I] =-1; layer [begin] = 0; L = H = 0; Q [L ++] = begin; while (H <L) {k = Q [H ++]; for (I = head [k]; I! =-1; I = edge [I]. next) {Y = edge [I]. v; If (edge [I]. cap> 0 & layer [y] =-1) {layer [y] = layer [k] + 1; if (y = END) return true; Q [L ++] = y ;}}return false;} int DFS (int x, int exp, int end) {mark [x] = 1; if (x = END) return exp; int y, temp, I; for (I = next [X]; I! =-1; I = edge [I]. next, next [x] = I) {Y = edge [I]. v; If (edge [I]. cap> 0 & layer [y] = layer [x] + 1 &&! Mark [y]) {If (temp = (DFS (Y, min (exp, edge [I]. CAP), end)> 0) {edge [I]. cap-= temp; // After the stream is complete, the forward stream indicates the remaining traffic edge [I ^ 1]. cap + = temp; // After the stream is complete, the reverse stream indicates the forward stream traffic return temp; }}return 0;} int dinic_flow (INT begin, int end) {int I, ans = 0, flow; while (BFS (begin, end) {for (I = 0; I <= end; I ++) next [I] = head [I]; while (true) {for (I = 0; I <= end; I ++) MARK [I] = 0; flow = DFS (begin, int_max, end); If (flow = 0) break; ans + = flow ;}} return ans ;}
Dinic non-recursive complexity O (V ^ 2 * E)
# Define n 20100 # define sta que // The Int level [N]; int P [N], P1 [N]; int ecnt; int que [N]; int n, m; struct edge {int V, next; int C;} e [900000]; void Init () {ecnt = 0; memset (p,-1, sizeof (p);} void insert (int u, int V, int C, int W) {e [ecnt]. V = V; E [ecnt]. C = C; E [ecnt]. next = P [u]; P [u] = ecnt ++; E [ecnt]. V = u; E [ecnt]. C = W; E [ecnt]. next = P [v]; P [v] = ecnt ++;} int dinic (INT St, int ed) {int ans = 0; int I, U, V, C; int head, rear, top; while (1) {// rebuild the hierarchy map memset (Level, 0, sizeof (level); Head = rear = 0; level [st] = 1; que [rear ++] = sT; while (Head <rear) {u = que [head ++]; for (I = P [u]; I! =-1; I = E [I]. next) {v = E [I]. v; C = E [I]. c; If (C & level [v] = 0) {level [v] = level [u] + 1; que [rear ++] = V ;}}} if (level [ed] = 0) {// No augmented circuit break;} memcpy (P1, P, sizeof (P1); Top =-1; while (1) {If (top <0) {for (I = P1 [st]; I! =-1; I = E [I]. next) {v = E [I]. v; C = E [I]. c; If (C & P1 [v]! =-1 & level [v] = 2) break;} if (I> = 0) {sta [++ top] = I; p1 [st] = E [I]. next;} else break;} u = E [sta [Top]. v; If (u = ed) {// find an augmented path // The number of improvements to the Computing Stream, and record the edge int dd = max, Index =-1; for (I = 0; I <= top; I ++) of the next augmented path) {If (DD> E [sta [I]. c) {dd = E [sta [I]. c; Index = I ;}}ans + = dd; // adjust the residual network for (I = 0; I <= top; I ++) {// calculate the current residual network directly from the previous residual network. For more information, see Introduction to P401 E [sta [I]. c-= dd; E [sta [I] ^ 1]. c + = dd;} // trace back to a vertex in the path that may be extended. Points cannot be extended, so we can trace back to the previous vertex (1) for (I = 0; I <= top; I ++) {If (E [sta [I]. C = 0) {Top = index-1; break ;}} else {for (I = P1 [u]; I! =-1; I = E [I]. next) {v = E [I]. v; C = E [I]. c; If (C & P1 [v]! =-1 & level [u] + 1 = level [v]) break;} if (I! =-1) {sta [++ top] = I; P1 [u] = E [I]. next; // If the augmented path is found along edge I, P1 will be re-initialized; otherwise, it is determined that the vertex cannot be reached from edge I, and this edge will not be considered in future search. It is estimated that it can be ignored} else {p1 [u] =-1; top -- ;}}} return ans ;}
SAP non-recursive complexity O (V * E)
# Define n 440 # define m n * n # define INF 1 <30int head [N]; struct edge {int V, next, C;} edge [m]; int ecnt; void Init () {ecnt = 0; memset (Head,-1, sizeof (head);} void add (int u, int V, int W) {edge [ecnt]. V = V; edge [ecnt]. C = W; edge [ecnt]. next = head [u]; head [u] = ecnt ++; edge [ecnt]. V = u; edge [ecnt]. C = 0; edge [ecnt]. next = head [v]; head [v] = ecnt ++;} int SAP (int s, int T, int nodenum) {// source, sink, vertex number (non-vertex) int pre [N], c Ur [N], DIS [N], gap [N]; int flow = 0, Aug = inf; int U; bool flag; int I, J; for (I = 0; I <= nodenum; I ++) {cur [I] = head [I]; Gap [I] = dis [I] = 0 ;} gap [s] = nodenum; u = pre [s] = s; while (DIS [s] <nodenum) {flag = 0; For (j = cur [u]; j! =-1; j = edge [J]. next) {int v = edge [J]. v; If (edge [J]. c> 0 & dis [u] = dis [v] + 1) {flag = 1; cur [u] = J; Aug = min (Aug, edge [J]. c); Pre [v] = u; u = V; If (u = T) {flow + = Aug; while (u! = S) {u = pre [u]; edge [cur [u]. c-= Aug; // The positive stream of the edge continuously reduces edge [cur [u] ^ 1]. c + = Aug; // reflux increase} Aug = inf;} break;} If (FLAG) continue; If (-- gap [dis [u] = 0) break; For (DIS [u] = nodenum, j = head [u]; J! =-1; j = edge [J]. next) {int v = edge [J]. v; If (edge [J]. c> 0 & dis [v] <dis [u]) {dis [u] = dis [v]; cur [u] = J ;}} dis [u] ++; Gap [dis [u] ++; u = pre [u];} return flow ;}
ISAP + gap optimization complexity O (V ^ 2 * E)
# Define n 20010 # define M 500010int n, m; // n indicates the number of points M indicates the number of edges int H [N]; int gap [N]; int P [N], ecnt; int source, sink; struct edge {int V; int next; // int Val of the next edge; // Edge Weight} e [m]; inline void Init () {memset (p,-1, sizeof (p); ecnt = 0;} // directed inline void Add1 (int from, int, int Val) {e [ecnt]. V = to; E [ecnt]. val = val; E [ecnt]. next = P [from]; P [from] = ecnt ++; swap (from, to); e [ecnt]. V = to; E [ecnt]. val = 0; E [ecnt]. next = P [from]; P [From] = ecnt ++;} // undirected inline void Add2 (int from, int to, int Val) {e [ecnt]. V = to; E [ecnt]. val = val; E [ecnt]. next = P [from]; P [from] = ecnt ++; swap (from, to); e [ecnt]. V = to; E [ecnt]. val = val; E [ecnt]. next = P [from]; P [from] = ecnt ++;} inline int DFS (INT POs, int cost) {If (Pos = sink) {return cost ;} int J, Minh = n-1, Lv = Cost, D; For (j = P [POS]; J! =-1; j = E [J]. next) {int v = E [J]. v, val = E [J]. val; If (Val> 0) {If (H [v] + 1 = H [POS]) {If (LV <E [J]. val) d = lv; else d = E [J]. val; D = DFS (v, d); e [J]. val-= D; E [J ^ 1]. val + = D; LV-= D; If (H [Source]> = N) return cost-lv; If (Lv = 0) break ;} if (H [v] <Minh) Minh = H [v] ;}} if (Lv = cost) {-- gap [H [POS]; if (gap [H [POS] = 0) H [Source] = N; H [POS] = Minh + 1; ++ gap [H [POS];} return cost-lv;} int SAP (INT St, int ed) {source = sT; sink = Ed; int ans = 0; memset (GAP, 0, sizeof (GAP); memset (H, 0, sizeof (h); Gap [st] = N; while (H [st] <n) {ans + = DFS (St, int_max);} return ans ;}