当前位置 : 主页 > 手机开发 > harmonyos >

ZOJ 3209 Treasure Map DLX入门

来源:互联网 收集:自由互联 发布时间:2023-10-08
关键是建好图 把n*m的矩阵看成n*m个单位元,作为n*m列;每一个矩形一行。 问题即转化为从这些行中选择最少的一部分使每一列被覆盖且仅覆盖一次。 #includecstdio#define inf 10000000#define


关键是建好图

把n*m的矩阵看成n*m个单位元,作为n*m列;每一个矩形一行。

问题即转化为从这些行中选择最少的一部分使每一列被覆盖且仅覆盖一次。

#include<cstdio>
#define inf 10000000
#define N 1005
#define M 1024*505
int U[M],D[M],L[M],R[M],C[M];//C代表M所属的列,U,D,L,R为一个元素的上下左右指针
int H[505];//H是水平循环链表的头指针
int S[1005];//S代表每一列的元素个数
int size,n,m,p,ans;
void remove(int c)
{
    R[L[c]]=R[c],L[R[c]]=L[c];
    for(int i=D[c]; i!=c; i=D[i])
        for(int j=R[i]; j!=i; j=R[j])
            U[D[j]]=U[j],D[U[j]]=D[j],--S[C[j]];
}
void resume(int c)
{
    R[L[c]]=L[R[c]]=c;
    for(int i=U[c]; i!=c; i=U[i])
        for(int j=L[i]; j!=i; j=L[j])
            ++S[C[U[D[j]]=D[U[j]]=j]];
}
void Dance(int k)
{
    int i,j,tmp,c;
    if(!R[0])
    {
        if(k<ans)
		ans=k;
        return;
    }
    for(tmp=inf,i=R[0]; i; i=R[i])
        if(S[i]<tmp)tmp=S[c=i];
    remove(c);
    for(i=D[c]; i!=c; i=D[i])
    {
        for(j=R[i]; j!=i; j=R[j])remove(C[j]);
        Dance(k+1);
        for(j=L[i]; j!=i; j=L[j])resume(C[j]);//在这里遵循的原则是先删除的后还原,后删除的先还原。
    }
    resume(c);
}
void Link(int r,int c)
{
    ++S[C[size]=c];
    D[size]=D[c];
    U[D[c]]=size;
    U[size]=c;
    D[c]=size;
    if(H[r]<0)H[r]=L[size]=R[size]=size;
    else
    {
        R[size]=R[H[r]];
        L[R[H[r]]]=size;
        L[size]=H[r];
        R[H[r]]=size;
    }
    size++;
}
int main()
{
    int i,j,w,num,T,t;
    scanf("%d",&T);
    for(t=1;t<=T;t++)
    {
	ans=inf;
	size=0;
	scanf("%d %d %d",&n,&m,&p);
	int tem=n*m;
        for(i=0; i<=tem; ++i)
        {
            S[i]=0;
            D[i]=U[i]=i;
            L[i+1]=i;
            R[i]=i+1;
        }
        R[tem]=0;
	L[0]=tem;
        size=tem+1;
        for(i=1; i<=p; ++i)
        {
            H[i]=-1;
	    int a,b,c,d;
            scanf("%d %d %d %d",&a,&b,&c,&d);
			for(j=a;j<c;j++)
				for(w=b+1;w<=d;w++)
					Link(i,j*m+w);
        }
        Dance(0);
	if(ans==inf)
		printf("-1\n");
	else
		printf("%d\n",ans);
    }
    return 0;
}

 

上一篇:Codeforces Problem 37B - Computer Game
下一篇:没有了
网友评论