Test instructions: To the rows and columns of a number matrix of n rows M column, each element is not larger than K, ask if such a matrix exists, whether it is unique, the only one to find the individual elements N (1≤n≤400), M (1≤m≤400), K (1≤k≤40).
Title Link: http://acm.hdu.edu.cn/showproblem.php?pid=4888
-->> Building Map:
1) Super Source s = 0, super sink t = N + M + 1;
2) s to each row and each connected one edge, the capacity for that row and;
3) each row and to each column and the connection of one edge, the capacity is k;
4) Each column and one edge to T, the capacity for that column column and.
A row is connected to all the columns so that the row is diverted to the columns, which is the size of a column element of that row ...
So, if S to T the maximum flow = = All elements of the and, then there is a solution:
If there is a ring of length > 2 between the row and column nodes in the residual network (the self-loop length is 2, but the flow cannot be adjusted), then the traffic in this loop can be adjusted so that the traffic on the ring is not unique when the maximum flow is reached, that is, the matrix is not unique.
#include <cstdio> #include <cstring> #include <queue> #include <algorithm>using std::min;using std::queue;const int MAXN = 2 * 2 + 10;const int MAXM = + + * + * * Maxn;const int INF = 0x3f3f3f3f;struct edge{ int to; int cap; int flow; int NXT;} EDGE[MAXM << 1];int N, M, K;int sum;int S, T;int HED[MAXN], Ecnt;int CUR[MAXN], h[maxn];bool impossible, BUnique;voi D Init () {impossible = false; Bunique = true; ecnt = 0; memset (Hed,-1, sizeof (hed)); void Addedge (int u, int v, int cap) {edge[ecnt].to = v; Edge[ecnt].cap = cap; Edge[ecnt].flow = 0; EDGE[ECNT].NXT = Hed[u]; Hed[u] = ecnt++; edge[ecnt].to = u; Edge[ecnt].cap = 0; Edge[ecnt].flow = 0; EDGE[ECNT].NXT = Hed[v]; HED[V] = ecnt++;} BOOL Bfs () {memset (H,-1, sizeof (h)); Queue<int> Qu; Qu.push (S); H[s] = 0; while (!qu.empty ()) {int u = qu.front (); Qu.pop (); for (int e = Hed[u]; E! =-1; e = edge[e].nxt) {int v = edge[e].to; if (h[v] = =-1 && edge[e].cap > Edge[e].flow) {h[v] = H[u] + 1; Qu.push (v); }}} return h[t]! =-1;} int Dfs (int u, int cap) {if (U = = T | | cap = = 0) return cap; int flow = 0, subflow; for (int e = Cur[u]; E! =-1; e = edge[e].nxt) {Cur[u] = e; int v = edge[e].to; if (h[v] = = H[u] + 1 && (Subflow = Dfs (V, min (cap, edge[e].cap-edge[e].flow))) > 0) {Flow + = Subflow; Edge[e].flow + = Subflow; edge[e ^ 1].flow-= Subflow; Cap-= Subflow; if (cap = = 0) break; }} return flow;} int dinic () {int maxflow = 0; while (Bfs ()) {memcpy (cur, hed, sizeof (hed)); Maxflow + = Dfs (S, INF); } return maxflow;} void Read () {int r, C; int rsum = 0, csum = 0; S = 0; T = N + M + 1; for (int i = 1; I <= N; ++i) {SCANF ("%d", &r); Rsum + = r; Addedge (S, I, R); } for (int i = 1; I <= M; ++i) {scanf ("%d", &c); Csum + = C; Addedge (i + N, T, C); } if (rsum! = csum) {impossible = true; Return } sum = Rsum; for (int i = 1; I <= N; ++i) {for (int j = M; J >= 1;--j) {Addedge (i, J + N, K); }}}void checkpossible () {if (impossible) return; if (Dinic ()! = sum) {impossible = true; }}bool vis[maxn];bool checkcircle (int x, int f) {vis[x] = true; for (int e = hed[x]; E! =-1; e = edge[e].nxt) {if (Edge[e].cap > Edge[e].flow) {int v = edge[e].to; if (v = = f) Continue; if (Vis[v]) return true; else {if (checkcircle (v, x)) return true; }}} Vis[x] = false; return false;} void Checkunique () {if (impossible) return; memset (Vis, 0, sizeof (VIS)); for (int i = 1; I <= N; ++i) {if (Checkcircle (I,-1)) {Bunique = false; Return }}}void Output () {if (impossible) {puts ("impossible"); } else if (!bunique) {puts ("not Unique"); } else {puts ("Unique"); for (int i = 1; I <= N; ++i) {for (int e = Hed[i], j = 1; E! =-1 && j <= M; e = edge[e]. NXT, ++j) {printf ("%d", edge[e].flow); if (J < M) {printf (""); }} puts (""); }}}int Main () {while (scanf ("%d%d%d", &n, &m, &k) = = 3) {Init (); Read (); Checkpossible (); Checkunique (); Output (); } return 0;}
Hdu-4888-redraw Beautiful drawings (maximum flow)