#include<stdio.h>#include<string.h>#include<stdlib.h>#define M 32#define N 256int n,m;const int V=M*N;int U[V],D[V],C[V],R[V],L[V];int S[M],H[N];char s[M][M];int cc[M][M];int size,ak;bool hash[M];void Remove(int c){int i;for(i=D[c];i!=c;i=D[i])L[R[i]]=L[i],R[L[i]]=R[i];}void Resume(int c){int i;for(i=U[c];i!=c;i=U[i])L[R[i]]=R[L[i]]=i;}int h(){int r=0,i,j,k;memset(hash,false,sizeof(hash));for(i=R[0];i;i=R[i]){if(!hash[i]){r++;for(j=D[i];j!=i;j=D[j]){for(k=R[j];k!=j;k=R[k])hash[C[k]]=true;}}}return r;}void Dance(int k){int min,c,i,j;if(k+h()>=ak) return;//用大于号就超时了~if(!R[0]){if(k<ak) ak=k;return ;}for(min=V,i=R[0];i;i=R[i]){if(S[i]<min) min=S[i],c=i;}for(i=D[c];i!=c;i=D[i]){Remove(i);for(j=R[i];j!=i;j=R[j])Remove(j);Dance(k+1);for(j=L[i];j!=i;j=L[j])Resume(j);Resume(i);}}void Link(int r,int c){S[c]++;C[size]=c;U[size]=U[c];D[U[c]]=size;D[size]=c;U[c]=size;if(H[r]==-1)L[size]=R[size]=H[r]=size;else{L[size]=L[H[r]];R[L[H[r]]]=size;R[size]=H[r];L[H[r]]=size;}size++;} char str[20][20];int dx[]={0,0,1,-1};int dy[]={1,-1,0,0};int id[20][20];int ck[20][20];int main(){ int nu,num; while(scanf("%d%d",&n,&m)!=EOF) { for(int i=0;i<n;i++) { scanf("%s",str[i]); } num=0; nu=0; memset(id,0,sizeof(id)); memset(ck,0,sizeof(ck)); for(int i=0;i<n;i++) {for(int j=0;j<m;j++){if(str[i][j]=='#')id[i][j]=++num;if(str[i][j]=='.')ck[i][j]=++nu;} } int c=num; //************************* c为列的数量for(int i=0;i<=c;i++) {S[i]=0;U[i]=D[i]=i;L[i+1]=i;R[i]=i+1; } R[c]=0; size=c+1; memset(H,-1,sizeof(H)); //************************** for(int i=0;i<n;i++) for(int j=0;j<m;j++) {if(str[i][j]=='.'){for(int d=0;d<4;d++){int x=i,y=j;for(;x>-1&&y>-1&&x<n&&y<m&&str[x][y]=='.';x=x+dx[d],y=y+dy[d]);if(x>-1&&x<n&&y>-1&&y<m&&str[x][y]=='#')Link(ck[i][j],id[x][y]);}} } ak=m*n;//ak为所选函数 Dance(0); printf("%d\n",ak); } return 0;}