zoukankan      html  css  js  c++  java
  • 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.

    Input

    There are multiply test cases. First line: two integers N, M; The following N lines: Every line first comes an integer C(1 <= C <= 100), represents the number of 1s in this row, then comes C integers: the index of the columns whose value is 1 in this row.

    Output

    First output the number of rows in the selection, then output the index of the selected rows. If there are multiply selections, you should just output any of them. If there are no selection, just output "NO".

    Sample Input

    6 7
    3 1 4 7
    2 1 4
    3 4 5 7
    3 3 5 6
    4 2 3 6 7
    2 2 7
    

    Sample Output

    3 2 4 6

    DLX:精确覆盖和反复覆盖。此题是精确覆盖。

    学习资料;点击打开链接看了一下午。加上bin神的模板。算是懂了。

    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    #include<vector>
    #include<string>
    #include<iostream>
    #include<queue>
    #include<cmath>
    #include<map>
    #include<stack>
    #include<bitset>
    using namespace std;
    #define REPF( i , a , b ) for ( int i = a ; i <= b ; ++ i )
    #define REP( i , n ) for ( int i = 0 ; i < n ; ++ i )
    #define CLEAR( a , x ) memset ( a , x , sizeof a )
    typedef long long LL;
    typedef pair<int,int>pil;
    const int maxnnode=100100;
    const int maxn=1005 ;
    const int mod = 1000000007;
    struct DLX{
        int n,m,size;
        int U[maxnnode],D[maxnnode],L[maxnnode],R[maxnnode],Row[maxnnode],Col[maxnnode];
        int H[maxn],S[maxn];
        int ansd,ans[maxn];
        void init(int a,int b)
        {
            n=a;  m=b;
            REPF(i,0,m)
            {
                S[i]=0;
                U[i]=D[i]=i;
                L[i]=i-1;
                R[i]=i+1;
            }
            R[m]=0; L[0]=m;
            size=m;
            REPF(i,1,n)
               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(int i=U[c];i!=c;i=U[i])
            {
                for(int j=L[i];j!=i;j=L[j])
                    ++S[Col[U[D[j]]=D[U[j]]=j]];
            }
            L[R[c]]=R[L[c]]=c;
        }
        bool Dance(int d)
        {
            if(R[0]==0)
            {
                ansd=d;
                return true;
            }
            int c=R[0];
            for(int i=R[0];i!=0;i=R[i])
            {
                if(S[i]<S[c])//选择1的数量最少的
                    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 true;
                for(int j=L[i];j!=i;j=L[j])  resume(Col[j]);
            }
            resume(c);
            return false;
        }
    };
    DLX L;
    int main()
    {
        int n,m;
        int x,y;
        while(~scanf("%d%d",&n,&m))
        {
            L.init(n,m);
            REPF(i,1,n)
            {
                scanf("%d",&x);
                while(x--)
                {
                    scanf("%d",&y);
                    L.link(i,y);
                }
            }
            if(!L.Dance(0))  printf("NO
    ");
            else
            {
                printf("%d",L.ansd);
                REP(i,L.ansd)
                    printf(" %d",L.ans[i]);
                printf("
    ");
            }
        }
        return 0;
    }
    


  • 相关阅读:
    mysql8.0 一次性备份导出/导入恢复所有数据库
    访问服务器共享资源不需要输帐号和密码
    win7 系统 提示用户'sa'登录失败
    Adoquery.disablecontrols和enablecontrols
    DBGridEh 导出数据到EXCEL文件
    Microsoft SQL Server 2005资料库(数据库)卸载方法
    64位操作系统下创建组件失败的解决办法
    U盘中的文件为什么看不见?
    解决错误提示unable to invoke code completion due to errors in source cord.
    浪潮服务器Windows Server系统异常断电导致系统中CentOS7虚拟机系统崩溃无法正常启动grub2故障修复error: relocation 0x48 is not implemented yet
  • 原文地址:https://www.cnblogs.com/bhlsheji/p/5381174.html
Copyright © 2011-2022 走看看