1 #include<cstdio>
  2 #include<cstring>
  3 #include<algorithm>
  4 #define MAXN 110
  5 #define MAXM 1000000
  6 #define INF 0x7FFFFFFF
  7 using namespace std;
  8 int G[MAXN][MAXN];
  9 int L[MAXM], R[MAXM], U[MAXM], D[MAXM];
 10 int size, ans, S[MAXM], H[MAXM], C[MAXM];
 11 bool vis[MAXN * 100];
 12 void Link(int r, int c)
 13 {
 14     U[size] = c;
 15     D[size] = D[c];
 16     U[D[c]] = size;
 17     D[c] = size;
 18     if (H[r] < 0)
 19         H[r] = L[size] = R[size] = size;
 20     else
 21     {
 22         L[size] = H[r];
 23         R[size] = R[H[r]];
 24         L[R[H[r]]] = size;
 25         R[H[r]] = size;
 26     }
 27     S[c]++;
 28     C[size++] = c;
 29 }
 30 void Remove(int c)
 31 {
 32     int i;
 33     for (i = D[c]; i != c; i = D[i])
 34     {
 35         L[R[i]] = L[i];
 36         R[L[i]] = R[i];
 37     }
 38 }
 39 void Resume(int c)
 40 {
 41     int i;
 42     for (i = D[c]; i != c; i = D[i])
 43         L[R[i]] = R[L[i]] = i;
 44 }
 45 int A()
 46 {
 47     int i, j, k, res;
 48     memset(vis, false, sizeof(vis));
 49     for (res = 0, i = R[0]; i; i = R[i])
 50     {
 51         if (!vis[i])
 52         {
 53             res++;
 54             for (j = D[i]; j != i; j = D[j])
 55             {
 56                 for (k = R[j]; k != j; k = R[k])
 57                     vis[C[k]] = true;
 58             }
 59         }
 60     }
 61     return res;
 62 }
 63 void Dance(int now)
 64 {
 65     if (R[0] == 0)
 66         ans = min(ans, now);
 67     else if (now + A() < ans)
 68     {
 69         int i, j, temp, c;
 70         for (temp = INF,i = R[0]; i; i = R[i])
 71         {
 72             if (temp > S[i])
 73             {
 74                 temp = S[i];
 75                 c = i;
 76             }
 77         }
 78         for (i = D[c]; i != c; i = D[i])
 79         {
 80             Remove(i);
 81             for (j = R[i]; j != i; j = R[j])
 82                 Remove(j);
 83             Dance(now + 1);
 84             for (j = L[i]; j != i; j = L[j])
 85                 Resume(j);
 86             Resume(i);
 87         }
 88     }
 89 }
 90 void Init(int m)
 91 {
 92     int i;
 93     for (i = 0; i <= m; i++)
 94     {
 95         R[i] = i + 1;
 96         L[i + 1] = i;
 97         U[i] = D[i] = i;
 98         S[i] = 0;
 99     }
100     R[m] = 0;
101     size = m + 1;
102 }
103 int main()
104 {
105     int n, m, i, j, k, r;
106     while (scanf("%d", &n), n)
107     {
108         scanf("%d", &m);
109         for (i = k = 0; i < n; i++)
110         {
111             for (j = 0; j < m; j++)
112             {
113                 scanf("%d", &G[i][j]);
114                 if (G[i][j])
115                     G[i][j] = ++k;
116             }
117         }
118         Init(k);
119         for (i = r = 0; i < n; i++)
120         {
121             H[++r] = -1;
122             for (j = 0; j < m; j++)
123             {
124                 if (G[i][j])
125                     Link(r, G[i][j]);
126             }
127         }
128         for (j = 0; j < m; j++)
129         {
130             H[++r] = -1;
131             for (i = 0; i < n; i++)
132             {
133                 if (G[i][j])
134                     Link(r, G[i][j]);
135             }
136         }
137         ans = min(n, m);
138         Dance(0);
139         printf("%d\n", ans);
140     }
141     return 0;
142 }
posted on 2012-07-26 21:21  DrunBee  阅读(238)  评论(0编辑  收藏  举报