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