Time Limit: 0.5 s
Space limit: 4 m
Question:
There is a network composed of pipelines, with N nodes (n not greater than 100). Node 1 can make raw materials and finally gather them to node n. Raw materials are transported through pipelines. Some of these nodes are connected by pipelines, which have the maximum traffic limit, and some of them must be filled. Calculate the minimum raw material manufacturing speed of Node 1. If the raw material cannot be transported to N, output "impossible"
Solution
First, there are upstream and downstream network streams. I do not have a deep understanding. After wa many times. It fully understands the algorithms of network streams with the upper and lower bounds.
First, we need to construct an adjoint network to determine whether all lower bounds can be satisfied and connected to source sink points.
Because it is the smallest stream, we need to know whether we can find an increasing path from the sink point to the source point. To reduce the maximum flow.
At this time, the negative flow may be obtained. If a new node 0 is added and a side with a capacity of-flow is added to the sink point, the negative flow can be changed to 0;
The specific constructor is in the program annotation.
/* Maximum stream algorithm with the upper and lower bounds of capacity 1) CAP (u, v) is the capacity of the edge from u to V 2) Gup (u, v) it is the upper bound of edge traffic between u and v. 3) glow (u, v) is the lower bound of edge traffic between u and v. 4) ST (u) represents the sum of the Lower Bounds of all outbound edges of a vertex u. 5) Ed (u) represents the sum of the Lower Bounds of all inbound edges of a vertex u. 6) s represents the Source Vertex, T is the construction method of the new network d of the sink point: 1) Add the virtual source point SS, ST 2) if the side (u, v) Capacity cap (u, v) = Gup (u, v)-glow (u, v) 3) for each vertex v, add an edge (SS, v) = ed (V); 4) for each vertex u, add edge (u, St) = ST (U); 5) CAP (t, s) = + ∞; 6) tflow calculates the maximum flow from SS to St for the sum of the lower bound of all edges. If the maximum flow is not equal to tflow, no feasible flow exists. This problem is not solved. Remove all edges connected to the SS and ST in the new network D. Find the maximum stream. Add the two stream values to the smallest stream, and run the second largest stream from t to S. */# Include <iostream> # include <cstdio> # include <cstring> # define MS (a, B) memset (a, B, sizeof A) using namespace STD; const int INF = 111; struct node {int U, V, C, next;} edge [INF * INF <2]; int Gup [INF] [INF], glow [INF] [INF], St [INF], Ed [INF], Cap [INF] [INF], tflow; int phead [INF * INF], SS, St, s, T, ncnt, ans; // both the arc and the reverse side are added. The initial size of the reverse side is 0 void addedge (int u, int V, int C) {edge [++ ncnt]. V = V, edge [ncnt]. U = u, Edge [ncnt]. C = C; edge [ncnt]. next = phead [u]; phead [u] = ncnt; edge [++ ncnt]. V = u, edge [ncnt]. U = V, edge [ncnt]. C = 0; edge [ncnt]. next = phead [v]; phead [v] = ncnt;} int SAP (INT pstart, int pend, int N) {int numh [INF], H [INF], curedge [INF], pre [INF]; int cur_flow, flow_ans = 0, U, neck, I, TMP; MS (H, 0); MS (numh, 0 ); MS (PRE,-1); for (I = 0; I <= N; I ++) curedge [I] = phead [I]; numh [0] = N; U = Pstart; while (H [pstart] <= N) {If (u = pend) {cur_flow = 1e9; for (I = pstart; I! = Pend; I = edge [curedge [I]. v) if (cur_flow> edge [curedge [I]. c) Neck = I, cur_flow = edge [curedge [I]. c; for (I = pstart; I! = Pend; I = edge [curedge [I]. v) {TMP = curedge [I]; edge [TMP]. c-= cur_flow, edge [TMP ^ 1]. c + = cur_flow;} flow_ans + = cur_flow; u = neck;} for (I = curedge [u]; I! = 0; I = edge [I]. Next) {If (edge [I]. V> N) continue; // important !!! If (edge [I]. C & H [u] = H [edge [I]. V] + 1) break;} if (I! = 0) {curedge [u] = I, pre [edge [I]. v] = u; u = edge [I]. v;} else {If (0 = -- numh [H [u]) continue; curedge [u] = phead [u]; for (TMP = n, I = phead [u]; I! = 0; I = edge [I]. Next) {If (edge [I]. V> N) continue; // important !!! If (edge [I]. c) TMP = min (TMP, H [edge [I]. v]);} H [u] = TMP + 1; ++ numh [H [u]; If (u! = Pstart) u = pre [u];} return flow_ans;} int solve (int n) {// create an adjoint network Ss = n + 1, St = n + 2; for (INT I = 1; I <= N; I ++) {If (Ed [I]) addedge (SS, I, Ed [I]); if (ST [I]) addedge (I, St, St [I]);} // t to s add an infinite capacity edge addedge (t, s, 0x7ffffff ); // determine the feasible stream int TEM = SAP (SS, St, St); If (TEM! = Tflow) Return-1; else {edge [ncnt]. C = edge [ncnt-1]. C = 0; // Delete the infinite capacity edge from S to t int kkk = SAP (T, S, T); return 1 ;}} int n, m, x, y, c, Sta; int main () {/* Create a graph, save the edge to the star, and the header is in phead []. The side counts ncnt. s, T are source points and sink points */scanf ("% d", & N, & M); ncnt = 1; for (INT I = 1; I <= m; I ++) {scanf ("% d", & X, & Y, & C, & Sta ); gup [x] [Y] = C; If (STA) {glow [x] [Y] = C; ST [x] + = C, ed [y] + = C; tflow + = C;} addedge (X, Y, Gup [x] [Y]-glow [x] [Y]);} S = 1, t = n; ans = 0; If (solve (n)> 0) {for (INT I = 2; I <= ncnt; I ++ = 2) {If (edge [I]. v <= T & edge [I]. U = 1) ans + = Gup [edge [I]. u] [edge [I]. v]-edge [I]. c; If (edge [I]. U <= T & edge [I]. V = 1) ans-= Gup [edge [I]. u] [edge [I]. v]-edge [I]. c ;}if (ANS <0) {S = 0; addedge (s, 1,-ans); ans = 0; SAP (S, T, T );} printf ("% d \ n", ANS); For (INT I = 2; I <= 2 * m; I + = 2) printf ("% d ", gup [edge [I]. u] [edge [I]. v]-edge [I]. c);} else puts ("impossible"); Return 0 ;}View code
Sgu 176. Flow Construction