"HDU" 4888 Redraw Beautiful Drawings Network Flow "infer if the solution is unique"

Source: Internet
Author: User

Portal:

pid=4888 ">" HDU "4888 Redraw Beautiful drawings


Topic Analysis:

The game saw a network flow, but did not knock out. A variety of negative examples to tear themselves down (the reason is not willing to write violence inference).


The first is a simple row to build the edge. The source point builds edges to the row. The capacity is the line element and, the sink point, and the Lie Jian edge. The capacity is for the column element and. All rows to all Lie Jian edges, with a capacity of K.

Run the maximum flow one time. Marue have the solution, otherwise there is no solution.

The next step is to infer whether the solution is unique.

The puzzle is not understood at all. Or a violent dafa good.

The simplest idea is to enumerate the four ends of a rectangle. Set the endpoint on the main diagonal of a and d. B, C is the endpoint on the vice-diagonal. Only A, d is not equal to K and B, C is not equal to 0, then there is solution.

The corresponding only to B, C is not equal to K and a, d is not equal to 0, then the same solution.

So. Enumerating all of the rectangle complexity up to O (n^4), too large, we need to reduce the complexity.

So how do we reduce the complexity?

Now we set up a two-dimensional array can[I [j] means that there is a row in the line before the current row that satisfies the element of column I is not equal to 0 and the element of column J is not equal to K, then can[I [j] = 1, assuming that the bank also satisfies column I is not equal to K and column J is not equal to That means there are multiple solutions. Otherwise the can[J [i] is marked as 1. Then proceed with the scan.

The above procedure infers the output solution after the unique solution. (I, j) The corresponding element is the flow of the opposite edge of row I to column J.


The code is as follows:


#include <cstdio> #include <cstring> #include <algorithm>using namespace std; #define REP (I, A, b) for (int i = A; I < b; + + i) #define for (I, A, b) for (int i = A; I <= B; + + i) #define REV (I, A, b) for (int i = a-1; I >= b;--i) #define FOV (I, A, b) for (int i = A; I >= b;--i) #define CLR (A, x) MEMS ET (A, X, sizeof a) #define CPY (A, X) memcpy (A, x, sizeof a) const int MAXM = 405; Const int MAXN = 1005; const int MAXQ = 500000; const int maxe = 500000; const int INF = 0x3f3f3f3f; struct Edge {int V, c, N; Edge () {}edge (int v, int c, int n): V (v), C (c), n (n) {}}, struct NetWork {Edge e[maxe]; int H[MAXN], cn TE; int D[MAXN], CUR[MAXN], NUM[MAXN], PRE[MAXN]; int Q[MAXQ], head, tail; int n, m, k; int s, T, NV; int flow; I NT ROW[MAXN], COL[MAXN]; int G[MAXM][MAXM]; int CAN[MAXM][MAXM]; void init () {cnte = 0; CLR (H,-1);} void Addedge (int u, int v, int c) {E[cnte] = Edge (V,C, H[u]); H[u] = Cnte + +; E[cnte] = Edge (u, 0, h[v]); H[V] = Cnte + +;} void Rev_bfs () {CLR (d,-1); CLR (num, 0); head = tail = 0; Q[tail + +] = t;d [t] = 0; num[d[t]] = 1; while (head! = tail) {int u = q[head + +]; for (int i = h[u]; ~i; i = E[I].N {int v = e[i].v, if (~d[v]) continue;d [v] = D[u] + 1; num[d[v]] + +; Q[tail + +] = V;}}}  int Isap () {CPY (cur, H); Rev_bfs (); flow = 0; int u = pre[s] = s, i; while (D[s] < NV) {if (U = = t) {int f = INF, POS; for (i = s; I! = t; i = E[CUR[I]].V) if (F > e[cur[i]].c) {f = e[cur[i]].c;p os = i;} for (i = s; I! = t; i = E[CUR[I]].V) {e[cur[i]].c-= f; E[cur[i] ^ 1].c + = f; Flow + = f; u = pos;} for (i = cur[u]; ~i, i = E[I].N) if (e[i].c && d[u] = = D[E[I].V] + 1) break; if (~i) {Cur[u] = i;p re[e[i].v ] = u; u = e[i].v;}  else {if (0 = = (--num[d[u]])) break, int mmin = NV, for (i = h[u]; ~i; i = E[I].N) if (e[i].c && mmin > D[E[I].V]) {Cur[u] = i; mmin = d[e[i].v];} D[U] = mmin + 1; num[d[u]] + +; u = Pre[u];}} return flow;} void put () {printf ("unique\n"); For (i, 1, N) for (j, 1, m) printf ("%d%c", G[i][j], J < m? ': ' \ n ');} void Build () {for (U, 1, n) for (int i = h[u]; ~i; i = E[I].N) if (E[I].V) g[u][e[i].v-n] = e[i ^ 1].c;} int check () {CLR (can, 0); For (R, 1, N) for (I, 1, M) for (J, i + 1, m) {int tmp1 = 0, tmp2 = 0; if (g[r][i]! = k && G[r][j]! = 0) {if (Can[i][j]) return 1; tmp1 = 1;} if (g[r][i]! = 0 && g[r][j]! = k) {if (Can[j][i]) return 1; tmp2 = 1;} if (TMP1) can[j][i] = TMP1; if (TMP2) can[i][j] = TMP2;} return 0;} void Solve () {int sum1 = 0; int sum2 = 0; init (); s = 0; t = n + m + 1; NV = t + 1; For (i, 1, n) {scanf ("%d", &row[i]), Addedge (S, I, Row[i]); SUM1 + = Row[i];} For (I, 1, m) {scanf ("%d", &col[i]), Addedge (i + N, T, Col[i]); sum2 + = Col[i];} For (i, 1, N) for (j, 1, m) Addedge (i, n + j, k); Isap (); if (floW! = Sum1 | | Flow! = sum2) {printf ("impossible\n"); return;} Build (); int multi = Check (), if (multi) printf ("Not unique\n"); Elseput ();}} NW; int main () {while (~scanf ("%d%d%d", &AMP;NW.N, &AMP;NW.M, &AMP;NW.K)) nw.solve (); return 0;}

The solution is still not understood, but the Dfs method will be. The thought is similar to the above, looking for the ring with the thought of backtracking. It is known that a ring of length equal to 2 is not feasible (since both points are self) and must be a ring with a length greater than or equal to 4 (which can form a ring with an even length). We only want to backtrack on each line, assuming that the flow capacity along the rows to the column can be reduced (the elements that belong to the larger) or column to row and capacity can be reduced (rows to columns and capacity can be added, belonging to the elements can be smaller) to find the ring on the side to explain the multi-solution.


The code is as follows:


#include <cstdio> #include <cstring> #include <algorithm>using namespace std; #define REP (I, A, b) for (int i = A; I < b; + + i) #define for (I, A, b) for (int i = A; I <= B; + + i) #define REV (I, A, b) for (int i = a-1; I >= b;--i) #define FOV (I, A, b) for (int i = A; I >= b;--i) #define CLR (A, x) MEMS  ET (A, X, sizeof a) #define CPY (A, X) memcpy (A, x, sizeof a) const int MAXM = 1005; Const int MAXN = 1005; const int MAXQ = 2000000; Const int maxe = 2000000; Const int INF = 0x3f3f3f3f; struct Edge {int V, c, N; Edge () {}edge (int v, int c, int n): V (v), C (c), n (n) {}}, struct NetWork {Edge e[maxe]; int H[MAXN], cn TE; int D[MAXN], CUR[MAXN], NUM[MAXN], PRE[MAXN]; int Q[MAXQ], head, tail; int n, m, k; int s, T, NV; int flow; I NT ROW[MAXN], COL[MAXN]; int G[MAXM][MAXM]; int VIS[MAXN]; void init () {cnte = 0; CLR (H,-1);} void Addedge (int u, int v, int c) {E[cnte] = Edge (V, C, H[u]); H[u] = Cnte + +; E[cnte] = Edge (u, 0, h[v]); H[V] = Cnte + +;} void Rev_bfs () {CLR (d,-1); CLR (num, 0); head = tail = 0; Q[tail + +] = t;d [t] = 0; num[d[t]] = 1; while (head! = tail) {int u = q[head + +]; for (int i = h[u]; ~i; i = E[I].N {int v = e[i].v, if (~d[v]) continue;d [v] = D[u] + 1; num[d[v]] + +; Q[tail + +] = V;}}}  int Isap () {CPY (cur, H); Rev_bfs (); flow = 0; int u = pre[s] = s, i; while (D[s] < NV) {if (U = = t) {int f = INF, POS; for (i = s; I! = t; i = E[CUR[I]].V) if (F > e[cur[i]].c) {f = e[cur[i]].c;p os = i;} for (i = s; I! = t; i = E[CUR[I]].V) {e[cur[i]].c-= f; E[cur[i] ^ 1].c + = f; Flow + = f; u = pos;} for (i = cur[u]; ~i, i = E[I].N) if (e[i].c && d[u] = = D[E[I].V] + 1) break; if (~i) {Cur[u] = i;p re[e[i].v ] = u; u = e[i].v;}  else {if (0 = = (--num[d[u]])) break, int mmin = NV, for (i = h[u]; ~i; i = E[I].N) if (e[i].c && mmin > D[E[I].V]) {Cur[u] = i; mmin = d[e[i].v];} D[u] = Mmin + 1; num[d[u]] + +; u = Pre[u];}} return flow;} void put () {printf ("unique\n"); for (U, 1, n) for (int i = h[u]; ~i; i = e[i].n) {int v = E[I].V; G[u][v-n] = e[i ^ 1].c;} For (i, 1, N) for (j, 1, m) printf ("%d%c", G[i][j], J < m? ': ' \ n ');} int dfs (int u, int fa) {if (Vis[u]) return 1; Vis[u] = 1; for (int i = h[u]; ~i; i = e[i].n) {int v = E[I].V; if (v! = FA && e[i].c && v! = s && v! = t) if (DFS (v, u)) return 1;} Vis[u] = 0; return 0;} void Solve () {int sum1 = 0; int sum2 = 0; init (); s = 0; t = n + m + 1; NV = t + 1; For (i, 1, n) {scanf ("%d", &row[i]), Addedge (S, I, Row[i]); SUM1 + = Row[i];} For (I, 1, m) {scanf ("%d", &col[i]), Addedge (i + N, T, Col[i]); sum2 + = Col[i];} For (i, 1, N) for (j, 1, m) Addedge (i, n + j, k); Isap (); if (flow! = SUM1 | | Flow! = sum2) {printf ("Impos Sible\n "); return;} int flag = 1; CLR (Vis, 0); For (i, 1, n) {if (!flag) Break, if (Dfs (i, 0)) flag = 0;} if (!flag) printf ("Not unique\n"); Elseput ();}} NW; int main () {while (~scanf ("%d%d%d", &AMP;NW.N, &AMP;NW.M, &AMP;NW.K)) nw.solve (); return 0;}


"HDU" 4888 Redraw Beautiful Drawings Network Flow "infer if the solution is unique"

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.