HUST 1017 - Exact cover (Dancing Links 模板题)

一个DLX模板阿

/*

1 0 0 1 0 0 1

1 0 0 1 0 0 0

0 0 0 1 1 0 1

0 0 1 0 1 1 0

0 1 1 0 0 1 1

0 1 0 0 0 0 1



2 4 6



1 0 0 1 0 0 0

0 0 1 0 1 1 0

0 1 0 0 0 0 1

*/



#include <stdio.h>

#include <string.h>

#include <iostream>

#include <algorithm>

#include <vector>

#include <queue>

#include <set>

#include <map>

#include <string>

#include <math.h>

#include <stdlib.h>

#include <time.h>

using namespace std;

const int maxnode = 100010;

const int MaxM = 1010;

const int MaxN = 1010;

struct DLX{

    int i, j, n, m, size;

    int U[maxnode],D[maxnode],R[maxnode],L[maxnode],Row[maxnode],Col[maxnode];

    int H[MaxN], S[MaxM];

    int ansd, ans[MaxN];

    void init(int _n,int _m){

        n = _n;

        m = _m;

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

            S[i] = 0;

            U[i] = D[i] = i;

            L[i] = i-1;

            R[i] = i+1;

        }

        R[m] = 0; L[0] = m;

        size = m;

        for(i = 1;i <= n;i++)

            H[i] = -1;

    }

    void Link(int r,int c){

        ++S[Col[++size]=c];

        Row[size] = r;

        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;

        }

    }

    void remove(int c){

        L[R[c]] = L[c]; R[L[c]] = R[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[Col[j]];

            }

    }

    void resume(int c){

        for(i = U[c];i != c;i = U[i])

            for(j = L[i];j != i;j = L[j])

                ++S[Col[U[D[j]]=D[U[j]]=j]];

        L[R[c]] = R[L[c]] = c;

    }

    //d为递归深度

    bool Dance(int d){

        if(R[0] == 0)

        {

            ansd = d;

            return true;

        }

        int c = R[0];

        for(i = R[0];i != 0;i = R[i])

            if(S[i] < S[c])

                c = i;

        remove(c);

        for(i = D[c];i != c;i = D[i])

        {

            ans[d] = Row[i];

            for(j = R[i]; j != i;j = R[j])remove(Col[j]);

            if(Dance(d+1))return true;

            for(j = L[i]; j != i;j = L[j])resume(Col[j]);

        }

        resume(c);

        return false;

    }

};



DLX g;



int main(){

    int n, m, i, j, k, num;

    while(EOF != scanf("%d%d",&n,&m)){

        g.init(n,m);

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

            scanf("%d",&num);

            while(num--){

                scanf("%d",&j);

                g.Link(i,j); // Insert "j" into i ROW

            }

        }

        if(!g.Dance(0))printf("NO\n");

        else

        {

            printf("%d",g.ansd);

            for(i = 0;i < g.ansd;i++)

                printf(" %d",g.ans[i]);

            printf("\n");

        }

    }

    return 0;

}

 

你可能感兴趣的:(link)