POJ 1084(DLX重复覆盖)

来源:互联网 发布:淘宝扣分12分会怎么样 编辑:程序博客网 时间:2024/04/30 10:18

问题描述:用棍子摆成一个n×n的正方形,问你最少取走多少根棍子可以使图中,任一正方形都是不完整的。


DLX重复覆盖,把棍子看作行,对应的矩阵看作列,那么选择棍子就是选择棍子对应的行并覆盖该行所包括的列。


代码如下:

/*--------------------------------------------------------                       Author:log                            Created Time:2016年06月10日 星期五 11时03分57秒--------------------------------------------------------*/#include <iostream>#include <cstdio>#include <cstring>#include <cmath>#include <algorithm>#include <vector>#include <stack>#include <queue>#include <map>using namespace std;const int maxn=100;const int maxnn=maxn*maxn;int L[maxnn],R[maxnn],U[maxnn],D[maxnn];int C[maxnn],S[maxnn],V[maxn];bool vis[maxn];int cot;void init(int n,int m){for(int i=0;i<=m;i++){C[i]=U[i]=D[i]=i;L[i+1]=i;R[i]=i+1;S[i]=0;}L[0]=m;R[m]=0;cot=m;for(int i=0;i<=n;i++)V[i]=0;}void link(int i,int j){S[C[++cot]=j]++;D[cot]=j;U[cot]=U[j];if(V[i])L[cot]=V[i],R[cot]=R[V[i]];else L[cot]=R[cot]=cot;V[i]=cot;D[U[cot]]=cot;U[D[cot]]=cot;L[R[cot]]=cot;R[L[cot]]=cot;}void remove(int c){for(int i=D[c];i!=c;i=D[i]){L[R[i]]=L[i];R[L[i]]=R[i];}}void resume(int c){for(int i=U[c];i!=c;i=U[i]){R[L[i]]=i;L[R[i]]=i;}}int Hash(){memset(vis,0,sizeof(vis));int res=0;for(int i=R[0];i!=0;i=R[i]){if(vis[C[i]])continue;//printf("1\n");res++;vis[C[i]]=true;for(int j=D[i];j!=i;j=D[j]){//printf("2\n");for(int k=R[j];k!=j;k=R[k]){//printf("3\n");vis[C[k]]=true;}}}//printf("4\n");return res;}int ans;void dance(int k){int c=0,s=maxn;if(R[0]==0){ans=k;return;}if(k+Hash()>ans)return;for(int i=R[0];i!=0;i=R[i])if(S[i]<s)s=S[c=i];//printf("c:%d\n",c);for(int i=D[c];i!=c;i=D[i]){remove(i);for(int j=R[i];j!=i;j=R[j])remove(j);dance(k+1);for(int j=L[i];j!=i;j=L[j])resume(j);resume(i);}}vector<int>have[maxn];bool sel[maxn];void build(int n){for(int i=1;i<=2*n*(n+1);i++)have[i].clear();int k=1;for(int i=1;i<=n;i++){for(int st=0;st<=2*n*(n+1)-n-i*(n+n+1);st+=n+n+1){for(int j=0;j<n-i+1;j++){for(int h=0;h<i;h++)have[k].push_back(st+j+h);for(int h=0;h<i;h++)have[k].push_back(st+j+n+h*(n+n+1));for(int h=0;h<i;h++)have[k].push_back(st+j+i+n+h*(n+n+1));for(int h=0;h<i;h++)have[k].push_back(st+j+i*(n+n+1)+h);k++;}}}init(2*n*(n+1),k-1);bool flag;for(int i=1;i<k;i++){flag=true;for(int j=0;j<have[i].size()&&flag;j++)if(sel[have[i][j]])flag=false;if(!flag){L[R[i]]=L[i];R[L[i]]=R[i];continue;}for(int j=0;j<have[i].size();j++)link(have[i][j],i);}}int main(){int n,m,temp;int t;scanf("%d",&t);while(t--){scanf("%d",&n);scanf("%d",&m);memset(sel,0,sizeof(sel));for(int i=0;i<m;i++){scanf("%d",&temp);sel[temp-1]=true;}build(n);/*for(int i=0;i<=cot;i++){printf("%d:U=%d,D=%d,L=%d,R=%d\n",i,U[i],D[i],L[i],R[i]);}*/ans=maxnn;dance(0);printf("%d\n",ans);}    return 0;}


0 0
原创粉丝点击