• POJ 3740 Dancing Links


    Dancing Links学习:http://www.cnblogs.com/steady/archive/2011/03/15/1984791.html

    以及图文学习:http://www.cnblogs.com/grenet/p/3145800.html

    思路:这题是Dancing Links即DLX的最简单题目了吧,看懂了这个知识点之后。也不想自己敲了。然后搜索了好多个代码模板。认为这个我比較好理解也比較好掌握。然后就用这个模板了。

    #include<iostream>
    #include<cstring>
    #include<string>
    #include<cstdio>
    #include<algorithm>
    #include<vector>
    using namespace std;
    #define MAXN  350*30+30
    #define INF 0xFFFFFF
    int head,sz;
    int U[MAXN],D[MAXN],L[MAXN],R[MAXN];//上下左右链表指针
    int H[MAXN],ROW[MAXN],C[MAXN],S[MAXN],O[MAXN];
    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[C[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[C[j]];
                U[D[j]]=j;
                D[U[j]]=j;
            }
        }
        L[R[c]]=c;
        R[L[c]]=c;
    }
    bool dfs(int k)
    {
        if(R[head]==head)
            return  true;
        int s=INF,c;
        for (int t=R[head]; t!=head; t=R[t])
            if (S[t]<s) s=S[t],c=t;
        remove(c);
        for(int i=D[c]; i!=c; i=D[i])
        {
            O[k]=ROW[i];
            for(int j=R[i]; j!=i; j=R[j])
                remove(C[j]);
            if(dfs(k+1)) return  true;
            for(int j=L[i]; j!=i; j=L[j])
                resume(C[j]);
        }
        resume(c);
        return  false;
    }
    void init(int m)//m是列
    {
        head=0;//头指针为0
        for(int i=0; i<=m; i++)
        {
            U[i]=i;
            D[i]=i;//建立双向十字链表
            L[i]=i-1;
            R[i]=i+1;
            S[i]=0;
        }
        R[m]=0;
        L[0]=m;
        S[0]=INF+1;
        sz=m+1;
        memset(H,0,sizeof(H));
    }
    void insert(int i, int j)
    {
        if(H[i])
        {
            L[sz] = L[H[i]];
            R[sz] = H[i];
            L[R[sz]] = sz;
            R[L[sz]] = sz;
        }
        else
        {
            L[sz] = sz;
            R[sz] = sz;
            H[i] = sz;
        }
        U[sz] = U[j];
        D[sz] = j;
        U[D[sz]] = sz;
        D[U[sz]] = sz;
        C[sz] = j;
        ROW[sz] = i;
        ++S[j];
        ++sz;
    }
    int main()
    {
        //freopen("1.txt","r",stdin);
        int n,m,x;
        while(~scanf("%d%d",&n,&m))
        {
            init(m);
            for(int i=1;i<=n;i++)
                for(int j=1;j<=m;j++)
                {
                    scanf("%d",&x);
                    if(x) insert(i,j);
                }
            if(dfs(0)) //从头指针0開始遍历
                puts("Yes, I found it");
            else puts("It is impossible");
        }
        return 0;
    }
    


  • 相关阅读:
    confluence重置admin密码
    oracle 11g密码永不过期
    GCC编译器使用
    Emacs常用命令汇总
    bash shell命令(1)
    进程管理3--经典的进程同步问题
    进程管理2--进程的同步与信号量
    C安全问题与指针误用
    C迷途指针
    进程管理1--进程的概念与操作
  • 原文地址:https://www.cnblogs.com/lcchuguo/p/5389754.html
Copyright © 2020-2023  润新知