DLX 模板

//以hust1017为例

#include<stdio.h>
#include<string.h>

#define N 1100
#define M 1100
#define V N*M

#define INF 100000000

int D[V+1],U[V+1],L[V+1],R[V+1],C[V+1],mark[V+1];
int S[M+1],H[N+1];

void remove(int c){
	int i,j;
	R[L[c]]=R[c];
	L[R[c]]=L[c];
	for(i=D[c];i!=c;i=D[i])
		for(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)
{
	int i,j;
	for(i=U[c];i!=c;i=U[i])
		for(j=L[i];j!=i;j=L[j]) { U[D[j]]=j; D[U[j]]=j; ++S[C[j]]; }
	R[L[c]]=c;L[R[c]]=c;
}

int size;

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) H[r]=L[size]=R[size]=size;
    else {
        L[size]=L[H[r]];R[L[H[r]]]=size;
        R[size]=H[r];L[H[r]]=size;
    }
    mark[size]=r;
    ++size;
}

int O[N+1],head,n,m;

int dfs(int k)
{
	int i,j,c,Max=INF;
	if(R[head]==head)
	{
		printf("%d",k);
        for(i=0;i<k;i++)
            printf(" %d",mark[O[i]]);
        printf("\n");
		return 1;
	}
	for(i=R[head];i!=head;i=R[i])
		if(S[i]<Max){ c=i; Max=S[i]; }
	remove(c); 
	for(i=D[c];i!=c;i=D[i])
	{
		O[k]=i;
		for(j=R[i];j!=i;j=R[j]) remove(C[j]);
		if(dfs(k+1)) return 1;
		for(j=L[i];j!=i;j=L[j]) resume(C[j]);
	}
	resume(c);
	return 0;
}

void init(int m)
{
	int i;
	for(i=0;i<=m;i++) {
		S[i]=0;
		D[i]=U[i]=i;
		L[i+1]=i;R[i]=i+1;
	}
	R[m]=head=0;L[0]=m;size=m+1;
	memset(H,-1,sizeof(H));
	memset(mark,0,sizeof(mark));
}

int main() {
    int i,j,num;
    while(scanf("%d%d",&n,&m)!=EOF) {
		init(m);
        for(i=1;i<=n;i++) {
            scanf("%d",&num);
            while(num --) {
                scanf("%d",&j);
                Link(i , j);
            }
        }
        if(!dfs(0)) puts("NO");
    }
    return 0;
}


你可能感兴趣的:(DLX 模板)