(简单) HUST 1017 Exact cover , DLX+精确覆盖。

  Description

  There is an N*M matrix with only 0s and 1s, (1 <= N,M <= 1000). An exact cover is a selection of rows such that every column has a 1 in exactly one of the selected rows. Try to find out the selected rows.
 
  DLX精确覆盖的模板题。。。。。。
 
代码如下:
//HUST 1017

#include<iostream>
#include<cstring>

using namespace std;

// N 行 M 列 。 。 。

const int INF=10e8;

const int MaxN=1010;
const int MaxM=1010;
const int MaxNode=MaxN*MaxM;            // 这个的大小可以适当减少。 。 。

struct DLX
{
    int U[MaxNode],D[MaxNode],L[MaxNode],R[MaxNode],col[MaxNode],row[MaxNode];      //row 可以不要。
    int H[MaxN],S[MaxM];
    int size,n,m;
    int ansnum,ans[MaxN];

    void init(int _n,int _m)
    {
        n=_n;
        m=_m;
        size=m;
        ansnum=INF;

        for(int i=0;i<=m;++i)
        {
            L[i]=i-1;
            R[i]=i+1;
            U[i]=D[i]=i;

            S[i]=0;
        }
        R[m]=0;
        L[0]=m;

        for(int i=1;i<=n;++i)
            H[i]=-1;
    }

    void Link(int r,int c)
    {
        col[++size]=c;
        ++S[c];
        row[size]=r;

        U[size]=U[c];
        D[size]=c;
        D[U[c]]=size;
        U[c]=size;

        if(H[r]==-1)
            H[r]=L[size]=R[size]=size;
        else
        {
            L[size]=L[H[r]];
            R[size]=H[r];
            R[L[H[r]]]=size;
            L[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(int i=U[c];i!=c;i=U[i])
            for(int j=L[i];j!=i;j=L[j])
            {
                U[D[j]]=D[U[j]]=j;

                ++S[col[j]];
            }

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

    void showans(int d)
    {
        cout<<d;

        for(int i=0;i<d;++i)
            cout<<' '<<ans[i];

        cout<<endl;
    }

    bool Dance(int d)
    {
        if(R[0]==0)
        {
            showans(d);

            return 1;
        }

        int c=R[0];

        for(int i=R[0];i;i=R[i])
            if(S[i]<S[c])
                c=i;

        remove(c);

        for(int i=D[c];i!=c;i=D[i])
        {
            ans[d]=row[i];

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

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

            for(int j=L[i];j!=i;j=L[j])
                resume(col[j]);
        }

        resume(c);

        return 0;
    }
};

DLX dlx;

int main()
{
    ios::sync_with_stdio(false);

    int N,M,K;
    int t;

    while(cin>>N>>M)
    {
        dlx.init(N,M);

        for(int i=1;i<=N;++i)
        {
            cin>>K;

            for(int j=1;j<=K;++j)
            {
                cin>>t;

                dlx.Link(i,t);
            }
        }

        if(!dlx.Dance(0))
            cout<<"NO"<<endl;
    }

    return 0;
}
View Code

 

posted @ 2015-01-31 12:04  WhyWhy。  阅读(448)  评论(0编辑  收藏  举报