Hdu1532 & pku1273 drainage ditches (max stream EK algorithm)
Algorithm flow of this question
1. initialize pre
2. BFS for augmented path P
Does not exist: Break, return flow;
3. Calculate the minimum Aug value in P.
4. Modify the residual capacity in P and flow ++
Note:
1 ° BFS find the augmented path
2 ° prefix array pre Traversal
// Pku1273 hdu1532 # include <stdio. h> # include <string. h> # define v 300 # define INF limit int n, m; // represents the number of edges and number of vertices respectively. Mint C [v] [v]; // record residual capacity int EK (int s, int t) // Input Source Vertex S and sink vertex t {int queue [v], pre [v], U, V, p, q, Aug; int flow = 0; while (1) {memset (PRE,-1, sizeof (pre); // clear the last augmented path, used to record the parent node for (queue [p = q = 0] = s; P <= Q; P ++) // breadth-first search {u = queue [p]; for (V = 0; v <M & Pre [T] <0; V ++) // can it be optimized? If (C [u] [v]> 0 & Pre [v] <0) {pre [v] = u; queue [++ q] = V; // The upper limit of the queue is increased.} If (pre [T]> = 0) // the break of the vertex is found; // For exit point} If (pre [T] <0) break; // The cursor of the sink cannot be found, and there is no extended path // while exit point Aug = inf; // minimum record residual capacity for (u = pre [V = T]; V! = S; V = u, u = pre [u]) // find the minimum value if (Aug> C [u] [v]) in the augmented path. aug = C [u] [v]; for (u = pre [V = T]; V! = S; V = u, u = pre [u]) {C [u] [v]-= Aug; // residue capacity ---- C [v] [u] + = Aug; // anti-symmetry ++} flow ++ = Aug; // stream ++} return flow;} int main () {While (scanf ("% d", & N, & M )! = EOF) {int X, Y, cost; memset (C, 0, sizeof (c); For (INT I = 0; I <n; I ++) {scanf ("% d", & X, & Y, & cost); C [x-1] [Y-1] + = cost ;} printf ("% d \ n", EK (0 m-1);} return 0 ;}
After minor Optimization
// Pku1273 hdu1532 # include <stdio. h> # include <string. h >#define v 201 # define INF 2000000000int C [v] [v], n, m; int EK (int s, int t) {int I, j, U, v, Aug, flow, queue [v], p, q, pre [v]; flow = 0; while (1) {memset (PRE, 0, sizeof (pre); For (queue [p = q = 1] = s; P <= Q; P ++) {u = queue [p]; for (V = 1; v <= M & Pre [T] = 0; V ++) if (C [u] [v]> 0 & Pre [v] = 0) {pre [v] = u; queue [++ q] = V ;}} if (pre [T] = 0) break; Aug = inf; For (V = T; V! = S; V = pre [v]) if (Aug> C [pre [v] [v]) Aug = C [pre [v] [v]; flow + = Aug; For (V = T; V! = S; V = pre [v]) {C [pre [v] [v]-= Aug; // C [v] [pre [v] + = Aug; // This line is meaningless if it is not a bidirectional edge} return flow;} Main () {int S, e, cost, I; while (scanf ("% d", & N, & M )! = EOF) {memset (C, 0, sizeof (c); for (I = 1; I <= N; I ++) {scanf ("% d", & S, & E, & cost); C [s] [e] + = cost ;} printf ("% d \ n", EK (1, m ));}}