【HDU】3957 Street Fighter

  1 #include<cstdio>

  2 #include<cstring>

  3 #define MAXM 110

  4 #define MAXN 100000

  5 #define INF 0x7FFFFFFF

  6 bool G[MAXM][MAXM];

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

  8 int S[MAXN], X[MAXN], C[MAXN], H[MAXN];

  9 int size, depth;

 10 bool vis[MAXM], has[MAXM];

 11 void Init(int m) {

 12     int i;

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

 14     memset(G, false, sizeof(G));

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

 16         L[i + 1] = i;

 17         R[i] = i + 1;

 18         U[i] = D[i] = i;

 19         S[i] = 0;

 20         H[i] = -1;

 21     }

 22     R[m] = 0;

 23     size = m + 1;

 24 }

 25 void Link(int r, int c) {

 26     U[size] = c;

 27     D[size] = D[c];

 28     U[D[c]] = size;

 29     D[c] = size;

 30     if (H[r] < 0)

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

 32     else {

 33         L[size] = H[r];

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

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

 36         R[H[r]] = size;

 37     }

 38     S[c]++;

 39     X[size] = r;

 40     C[size++] = c;

 41 }

 42 int A() {

 43     int i, j, k, res;

 44     memset(has, false, sizeof(has));

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

 46         if (has[i])

 47             continue;

 48         res++;

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

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

 51                 has[C[k]] = true;

 52         }

 53     }

 54     return res;

 55 }

 56 void Remove(int c) {

 57     int i;

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

 59         L[R[i]] = L[i];

 60         R[L[i]] = R[i];

 61     }

 62 }

 63 void Resume(int c) {

 64     int i;

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

 66         L[R[i]] = R[L[i]] = i;

 67 }

 68 bool Dance(int now) {

 69     if (now + A() > depth)

 70         return false;

 71     if (R[0] == 0)

 72         return true;

 73     int i, j, c, temp;

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

 75         if (temp > S[i]) {

 76             temp = S[i];

 77             c = i;

 78         }

 79     }

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

 81         if (vis[X[i]] || vis[X[i] ^ 1])

 82             continue;

 83         vis[X[i]] = true;

 84         Remove(i);

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

 86             Remove(j);

 87         if (Dance(now + 1))

 88             return true;

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

 90             Resume(j);

 91         Resume(i);

 92         vis[X[i]] = false;

 93     }

 94     return false;

 95 }

 96 void Build(int n) {

 97     int i, j;

 98     for (i = 0; i < n; i++) {

 99         for (j = 0; j < n; j++) {

100             if (G[i][j])

101                 Link(i, j + 1);

102         }

103     }

104 }

105 int main() {

106     int T, ca = 1;

107     int n, m, i, j, k, x, y;

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

109     while (T--) {

110         scanf("%d", &n);

111         Init(n << 1);

112         for (i = 0; i < n; i++) {

113             scanf("%d", &m);

114             for (j = 0; j < m; j++) {

115                 scanf("%d", &k);

116                 while (k--) {

117                     scanf("%d%d", &x, &y);

118                     G[(i << 1) + j][(x << 1) + y] = true;

119                 }

120             }

121             if (m == 1) {

122                 for (k = 0; k < (n << 1); k++)

123                     G[k][(i << 1) + j] = true;

124             }

125             G[i << 1][i << 1] = G[i << 1 | 1][i << 1] = true;

126             G[i << 1][i << 1 | 1] = G[i << 1 | 1][i << 1 | 1] = true;

127         }

128         Build(n << 1);

129         for (depth = 1; depth < n && !Dance(0); depth++)

130             ;

131         printf("Case %d: %d\n", ca++, depth);

132     }

133     return 0;

134 }

你可能感兴趣的:(tree)