【POJ】1084 Square Destroyer

  1 #include<cstdio>

  2 #include<cstring>

  3 #include<vector>

  4 #include<algorithm>

  5 #define MAXM 80

  6 #define MAXN 100000

  7 #define INF 0x7FFFFFFF

  8 using namespace std;

  9 int L[MAXN], R[MAXN], U[MAXN], D[MAXN];

 10 int S[MAXN], H[MAXN], C[MAXN];

 11 int a[MAXM][MAXM], size, ans;

 12 bool exist[MAXM], vis[MAXM];

 13 vector<int> p[MAXM];

 14 void Init(int n, int m) {

 15     int i;

 16     for (i = 0; i <= m; i++) {

 17         L[i + 1] = i;

 18         R[i] = i + 1;

 19         U[i] = D[i] = i;

 20         S[i] = 0;

 21     }

 22     R[m] = 0;

 23     size = m + 1;

 24     m = n * (n + 1) << 1;

 25     for (i = 0; i <= m; i++)

 26         H[i] = -1;

 27 }

 28 inline void Link(int r, int c) {

 29     D[size] = D[c];

 30     U[size] = c;

 31     U[D[c]] = size;

 32     D[c] = size;

 33     if (H[r] < 0)

 34         H[r] = L[size] = R[size] = size;

 35     else {

 36         L[size] = H[r];

 37         R[size] = R[H[r]];

 38         L[R[H[r]]] = size;

 39         R[H[r]] = size;

 40     }

 41     S[c]++;

 42     C[size++] = c;

 43 }

 44 int A() {

 45     int i, j, k, res;

 46     memset(vis, false, sizeof(vis));

 47     for (res = 0, i = R[0]; i; i = R[i]) {

 48         if (vis[i])

 49             continue;

 50         res++;

 51         for (j = D[i]; j != i; j = D[j]) {

 52             for (k = R[j]; k != j; k = R[k])

 53                 vis[C[k]] = true;

 54         }

 55     }

 56     return res;

 57 }

 58 void Remove(int c) {

 59     int i;

 60     for (i = D[c]; i != c; i = D[i]) {

 61         L[R[i]] = L[i];

 62         R[L[i]] = R[i];

 63     }

 64 }

 65 void Resume(int c) {

 66     int i;

 67     for (i = D[c]; i != c; i = D[i])

 68         L[R[i]] = R[L[i]] = i;

 69 }

 70 void Dance(int now) {

 71     if (R[0] == 0)

 72         ans = min(ans, now);

 73     else if (now + A() < ans) {

 74         int i, j, temp, c;

 75         for (temp = INF,i = R[0]; i; i = R[i]) {

 76             if (temp > S[i]) {

 77                 temp = S[i];

 78                 c = i;

 79             }

 80         }

 81         for (i = D[c]; i != c; i = D[i]) {

 82             Remove(i);

 83             for (j = R[i]; j != i; j = R[j])

 84                 Remove(j);

 85             Dance(now + 1);

 86             for (j = L[i]; j != i; j = L[j])

 87                 Resume(j);

 88             Resume(i);

 89         }

 90     }

 91 }

 92 void Connect(int len, int row, int col, int r) {

 93     int i;

 94     for (i = row; i <= row + len; i++) {

 95         if (a[i][col] && exist[a[i][col]])

 96             p[a[i][col]].push_back(r);

 97         if (a[i][col + len] && exist[a[i][col + len]])

 98             p[a[i][col + len]].push_back(r);

 99     }

100     for (i = col + 1; i < col + len; i++) {

101         if (a[row][i] && exist[a[row][i]])

102             p[a[row][i]].push_back(r);

103         if (a[row + len][i] && exist[a[row + len][i]])

104             p[a[row + len][i]].push_back(r);

105     }

106 }

107 bool OK(int len, int row, int col) {

108     int i;

109     for (i = row; i <= row + len; i++) {

110         if (a[i][col] && !exist[a[i][col]])

111             return false;

112         if (a[i][col + len] && !exist[a[i][col + len]])

113             return false;

114     }

115     for (i = col + 1; i < col + len; i++) {

116         if (a[row][i] && !exist[a[row][i]])

117             return false;

118         if (a[row + len][i] && !exist[a[row + len][i]])

119             return false;

120     }

121     return true;

122 }

123 int Build(int n) {

124     int i, j, k, r;

125     memset(a, 0, sizeof(a));

126     for (i = 0; i < MAXM; i++)

127         p[i].clear();

128     for (i = k = r = 0; i < n; i++) {

129         if (i & 1) {

130             for (j = 0; j < n; j += 2)

131                 a[i][j] = ++k;

132         } else {

133             for (j = 1; j < n; j += 2)

134                 a[i][j] = ++k;

135         }

136     }

137     for (i = 2; i < n; i += 2) {

138         for (j = 0; j <= n - i; j += 2) {

139             for (k = 0; k <= n - i; k += 2) {

140                 if (OK(i, j, k)) {

141                     r++;

142                     Connect(i, j, k, r);

143                 }

144             }

145         }

146     }

147     return r;

148 }

149 int main() {

150     int T, n, m, i, j;

151     scanf("%d", &T);

152     while (T--) {

153         scanf("%d%d", &n, &m);

154         memset(exist, true, sizeof(exist));

155         for (i = 0; i < m; i++) {

156             scanf("%d", &j);

157             exist[j] = false;

158         }

159         i = Build((n << 1) + 1);

160         Init(n, i);

161         for (i = 1; i <= n * (n + 1) << 1; i++) {

162             for (j = 0; j < p[i].size(); j++)

163                 Link(i, p[i][j]);

164         }

165         ans = INF;

166         Dance(0);

167         printf("%d\n", ans);

168     }

169     return 0;

170 }

你可能感兴趣的:(des)