1. Title Description: Click to open the link
2. Problem-Solving ideas: The breakthrough lies in the modeling, in fact, the maximum flow of the most difficult problems are modeled. The subject only tells us the first row, the first I column and the value, let's solve the whole matrix. The and values of the first row and the value of column I are calculated beforehand. And what should we do? Since each element is between 1~20, if all the elements are subtracted by 1, then it is exactly between 0 19, so the capacity to associate to each edge is 19. At this point the and value of the line is subtracted by C, and the column and value minus R. Depending on the nature of the network stream: the traffic flowing into the node is equal to the flow of the outgoing node. It is therefore possible to construct a model from this point: assume that each row corresponds to an X-node, each column corresponds to a Y-node, and then increase the source point S, the meeting point T. For each node Xi, an arc is connected from S to Xi, and the capacity is a[i]-c (at this time all A[i],b[i] mean line I, column I and value); from Yi to T joins an arc, the capacity is b[i]-r. For each node (XI,YJ), an arc is connected from Xi to Yj, and the capacity is 19. Such a network satisfies all the properties of the previous topic. Then only the maximum flow of the s-t is calculated, so if the S departure and arrival T are fully loaded, the problem is solved. The flow of the junction Xi->yj is the value of the lattice (i,j) minus 1. A new knowledge point of the subject is the maximum upper bound of int: ~0u>>1, another knowledge point is the dinic algorithm using the list structure.
3. Code:
#define _crt_secure_no_warnings #include <iostream> #include <algorithm> #include <string> #include <sstream> #include <set> #include <vector> #include <stack> #include <map> #include < queue> #include <deque> #include <cstdlib> #include <cstdio> #include <cstring> #include < cmath> #include <ctime> #include <functional>using namespace std;const int INF = ~0u >> 1;// That is, the maximum struct of int dinic{static const int N = 510, M = 100010;int head[n];//The head of the list, storing the edge ordinal int en[m];//record Vint next[m];//record the next edge ordinal int cap[m];//record capacity int tot;//edge number void Clear () {memset (head, 0, sizeof (head)); tot = 1;} void Add (int u, int v, int w) {En[++tot] = V; Next[tot] = Head[u];head[u] = Tot;cap[tot] = w;} void Add (int u, int v, int w) {Add (U, V, W); Add (V, u, 0);} int D[n], cur[n];int N, S, T;bool BFs () {Queue<int>q;memset (d,-1, sizeof (d));d [s] = 0;q.push (s), while (!q.empty ()) { int x = Q.front (); Q.pop (); for (int k = head[x],v; k; k = next[k]) if (Cap[k] &&Amp D[v = en[k]]==-1) {D[v] = D[x] + 1;q.push (v);}} return d[t]! =-1;} int dfs (int x, int y) {if (x = = T | |!y) return y;int z = y;for (int&k = cur[x],v; k; k = next[k]) if (Cap[k] && D[v = En[k]] = = D[x] + 1) {int w = DFS (V, min (cap[k], z)), cap[k]-= w;//traffic increase means net capacity reduction Cap[k ^ 1] + = w;//Reverse edge capacity represents the flow of the forward edge Z-= w; if (!z) break;} if (z = = y) d[x] = -1;return y-z;} int Maxflow (int s, int t) {this->s = s, this->t = t;int flow = 0;while (BFS ()) {for (int i = 1; I <= n; i++) Cur[i] = Head[i];flow + = DFS (s, INF);} return flow;}} G;int r[25], c[25], R, C, rnd;void solve () {scanf ("%d%d", &r, &c); for (int i = 1; I <= R; i++) scanf ("%d", R + i) ; for (int i = 1; I <= C; i++) scanf ("%d", C + i), int s = r + C + 1, t = r + C + 2;G.N = R + C + 2;for (int i = 1; i < = R; i++) G.add (S, I, r[i]-r[i-1]-C);//r[i]-r[i-1] is the and value for the line i (int i = 1; I <= C; i++) G.add (R + I, T, C[i]-c[i-1]- R);//In the same vein, note that for the subscript of the district Branch and column, add a rfor (int i = 1; I <= r;i++) for (int j = 1; J <= C; j + +) G.add (i, R + j, +); G.maxflow (S, t);p rintf ("Matrix%d\n", ++rnd); for (int i = 1; I <= R; i++) {vector<int>ans;for (int k = g . Head[i]; K k = G.next[k]) if (g.en[k]! = g.s) ans.push_back (g.cap[k ^ 1] + 1); The capacity of the reverse side of the//k represents the flow of K for (int j = ans.size ()-1; J >= 0; J --)//Because the new edge is at the top of the list, so you want to reverse output printf ("%d%c", Ans[j], J? ': ' \ n ');}} int main () {//freopen ("T.txt", "R", stdin), int t;cin >> t;while (t--) {g.clear (); solve (); if (T) puts ("");} return 0;}
Example 11-8 Matrix decompression UVa11082