HDU 3529 Dancing link 重复覆盖

来源:互联网 发布:淘宝首页悬浮导航代码 编辑:程序博客网 时间:2024/06/10 19:04
#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;}


	
				
		
原创粉丝点击