【ZOJ】3209 Treasure Map

  1 #include<cstdio>
  2 #include<algorithm>
  3 #define INF 0x7FFFFFFF
  4 #define MAXN 450010
  5 using namespace std;
  6 int L[MAXN], R[MAXN], U[MAXN], D[MAXN], H[MAXN];
  7 int n, m, p, size, ans, C[MAXN], S[MAXN];
  8 void Init() {
  9     int i;
 10     n *= m;
 11     for (i = 0; i <= n; i++) {
 12         S[i] = 0;
 13         L[i + 1] = i;
 14         R[i] = i + 1;
 15         U[i] = D[i] = i;
 16     }
 17     R[n] = 0;
 18     size = n + 1;
 19 }
 20 void Remove(int c) {
 21     int i, j;
 22     L[R[c]] = L[c];
 23     R[L[c]] = R[c];
 24     for (i = D[c]; i != c; i = D[i]) {
 25         for (j = R[i]; j != i; j = R[j]) {
 26             U[D[j]] = U[j];
 27             D[U[j]] = D[j];
 28             S[C[j]]--;
 29         }
 30     }
 31 }
 32 void Resume(int c) {
 33     int i, j;
 34     L[R[c]] = c;
 35     R[L[c]] = c;
 36     for (i = D[c]; i != c; i = D[i]) {
 37         for (j = R[i]; j != i; j = R[j]) {
 38             U[D[j]] = j;
 39             D[U[j]] = j;
 40             S[C[j]]++;
 41         }
 42     }
 43 }
 44 inline void Link(int r, int c) {
 45     U[size] = c;
 46     D[size] = D[c];
 47     U[D[c]] = size;
 48     D[c] = size;
 49     if (H[r] < 0)
 50         H[r] = L[size] = R[size] = size;
 51     else {
 52         L[size] = H[r];
 53         R[size] = R[H[r]];
 54         L[R[H[r]]] = size;
 55         R[H[r]] = size;
 56     }
 57     S[c]++;
 58     C[size++] = c;
 59 }
 60 void Dance(int now) {
 61     if (R[0] == 0)
 62         ans = min(ans, now);
 63     else {
 64         int i, j, c, temp;
 65         for (temp = INF,i = R[0]; i; i = R[i]) {
 66             if (S[i] < temp) {
 67                 c = i;
 68                 temp = S[i];
 69             }
 70         }
 71         Remove(c);
 72         for (i = D[c]; i != c; i = D[i]) {
 73             for (j = R[i]; j != i; j = R[j])
 74                 Remove(C[j]);
 75             Dance(now + 1);
 76             for (j = L[i]; j != i; j = L[j])
 77                 Resume(C[j]);
 78         }
 79         Resume(c);
 80     }
 81 }
 82 int main() {
 83     int c, i, j, k, x1, y1, x2, y2;
 84     scanf("%d", &c);
 85     while (c--) {
 86         scanf("%d%d%d", &n, &m, &p);
 87         Init();
 88         for (i = 1; i <= p; i++) {
 89             H[i] = -1;
 90             scanf("%d%d%d%d", &x1, &y1, &x2, &y2);
 91             for (j = x1 + 1; j <= x2; j++) {
 92                 for (k = y1 + 1; k <= y2; k++)
 93                     Link(i, (j - 1) * m + k);
 94             }
 95         }
 96         ans = INF;
 97         Dance(0);
 98         if (ans != INF)
 99             printf("%d\n", ans);
100         else
101             puts("-1");
102     }
103     return 0;
104 }
原文地址:https://www.cnblogs.com/DrunBee/p/2604619.html