#include<stdio.h> #include<string.h> #include<stdlib.h> #define M 32 #define N 256 int 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; }
HDU 3529 Dancing link 重复覆盖
最新推荐文章于 2022-02-25 19:38:17 发布