ダンスチェーン(DLX)テンプレート.

3236 ワード

 
  
#define CL(a,num) memset((a),(num),sizeof(a))

#define inf 0x7f7f7f7f

#define M 1007

#define N 1000007



const int head = 0;

int u[N],d[N],l[N],r[N],c[N],row[N];

int s[M],o[M];

int ak,n,m;



void init(int m){

    int i;

    for (i = 1; i <= m; ++i){

        l[i] = i - 1;

        r[i] = i + 1;

        u[i] = d[i] = i;

        c[i] = i;

        s[i] = 0;

    }

    l[head] = m; r[head] = 1;

    r[m] = head;

}



void remove(int ci){

    int i,j;

    l[r[ci]] = l[ci];

    r[l[ci]] = r[ci];



    for (i = d[ci]; i != ci; 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 ci){

    int i,j;

    l[r[ci]] = r[l[ci]] = ci;

    for (i = u[ci]; i != ci; i = u[i]){

        for (j = l[i]; j != i; j = l[j]){

            u[d[j]] = d[u[j]] = j;

            s[c[j]]++;

        }

    }

}

int dfs(int k){

    int i,j;

    //      ,         ,   

    if (r[head] == head){

        ak = k;

        return 1;

    }

    //       1   

    int MIN = inf, ci = 0;

    for (i = r[head]; i != head; i = r[i]){

        if (s[i] < MIN){

            MIN = s[i];

            ci = i;

        }

    }

    remove(ci);//               

    for (i = d[ci]; i != ci; i = d[i]){

        for (j = r[i]; j != i; j = r[j]){

            remove(c[j]);//  i    c   ,            

        }

        o[k] = row[i];//    

        if (dfs(k + 1)) return 1;//     



    //i       i 

        for (j = l[i]; j != i; j = l[j]){

            resume(c[j]);

        }

    }

    resume(ci);

    return 0;

}

int main(){

    int i,j;

    int num,size;

    while (~scanf("%d%d",&n,&m)){

      //     

       init(m);

        size = m + 1;//     

        int x;

        for (i = 0; i < n; ++i){

            scanf("%d",&num);

            int rh = -1;

            for (j = 0; j < num; ++j){

                scanf("%d",&x);



                s[x]++;//  x     1

                c[size] = x;//   size   

                row[size] = i + 1;//   size   

        //   ,  

                u[size] = u[x];

                d[u[x]] = size;

                u[x] = size;

                d[size] = x;



        //   ,  

                if (rh == -1){

                    l[size] = r[size] = size;

                    rh = size;

                }

                else{

                    l[size] = l[rh];

                    r[l[rh]] = size;

                    l[rh] = size;

                    r[size] = rh;

                }

                size++;

            }

        }

        if (dfs(0)){

            printf("%d",ak);

            for (i = 0; i < ak; ++i) printf(" %d",o[i]);

            printf("
"); } else{ printf("NO
"); } } return 0; }
 
  

  

http://blog.csdn.net/mu399/article/details/7627736