Proof:
For each x node, there is only one inbound stream and multiple outbound streams (flow to each y node respectively). Obviously, the sum of multiple outbound streams is exactly the same as that of inbound streams. Similarly, for each y node, there are multiple inbound streams (from each x node), and there is only one outbound stream. Obviously, the sum of multiple inbound streams is equal to that of the outbound stream. The first type of arc uses the sum of all elements in each row as the capacity. The third type of arc uses the sum of all elements in each column as the capacity. The second type of arc uses the final traffic as each element in the matrix. That is to say, the first type of arc is divided into multiple branches, and each first type of arc is divided into one branch and remitted to the same third type of arc. Consider the matrix: divide the sum of each row into multiple elements. The sum of each row is divided into one element and arranged in the same column to form the sum of the columns. As long as the traffic of each second type of arc is obtained, every element in the matrix is obtained.
Note the graph creation skills
# Include <cstdio> # include <cstring> # include <queue> # include <vector> # include <algorithm> using namespace STD; const int maxn = 50 + 5; const int INF = 1000000000; struct edge {int from, to, Cap, flow; edge (int u, int V, int C, int F): From (u ), to (V), Cap (C), flow (f) {}}; struct edmondskarp {int n, m; vector <edge> edges; // double the number of edges vector <int> G [maxn]; // The adjacent table, G [I] [J] indicates the number of the J-th edge of node I in the E array int A [maxn]; // The improved I Nt p [maxn]; // input arc number of P in the shortest tree void Init (int n) {for (INT I = 0; I <n; I ++) G [I]. clear (); edges. clear ();} 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 (); G [from]. push_back (m-2); G [to]. push_back (m-1);} int maxflow (int s, int t) {int flow = 0; For (;) {memset (A, 0, sizeof ()); queue <int> q; q. push (s); A [s] = INF; while (! Q. empty () {int x = Q. front (); q. pop (); For (INT I = 0; I <G [X]. size (); I ++) {edge & E = edges [G [x] [I]; If (! A [E. to] & E. cap> E. flow) {P [E. to] = G [x] [I]; A [E. to] = min (A [X], E. the cap-e.flow); q. push (E. to) ;}} 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];} flow + = A [T];} return flow ;}}; edmondskarp g; int no [maxn] [maxn]; int main () {int T, R, C, V, Kase = 0; scanf ("% d", & T); For (INT Kase = 1; Kase <= T; kase ++) {scanf ("% d", & R, & C); G. init (R + C + 2); // initialization note R + C + 2 int last = 0; For (INT I = 1; I <= r; I ++) {scanf ("% d", & V); G. addedge (0, I, V-last-C); // row sum is V-last // s to line AI last = V;} Last = 0; for (INT I = 1; I <= C; I ++) {scanf ("% d", & V); G. addedge (R + I, R + C + 1, V-last-R); // Col sum is V-last // use R + J last = V ;} for (INT I = 1; I <= r; I ++) for (Int J = 1; j <= C; j ++) {G. addedge (I, R + J, 19); no [I] [J] = G. edges. size ()-2; // No [I] [J] is the index of Arc for cell (I, j)} //-2 is added because of reverse edge G. maxflow (0, R + C + 1); printf ("Matrix % d \ n", Kase); For (INT I = 1; I <= r; I ++) {for (Int J = 1; j <= C; j ++) printf ("% d", G. edges [No [I] [J]. flow + 1); // We subtracted 1 from every cell printf ("\ n");} printf ("\ n");} return 0 ;}
Uva11082 matrix decompressing