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 }
posted on 2012-07-30 22:27  DrunBee  阅读(367)  评论(0编辑  收藏  举报