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


  • 相关阅读:
    【乱侃】How do they look them ?
    【softeware】Messy code,some bug of Youdao notebook in EN win7
    【随谈】designing the login page of our project
    【web】Ad in security code, making good use of resource
    SQL数据库内存设置篇
    关系数据库的查询优化策略
    利用SQL未公开的存储过程实现分页
    sql语句总结
    sql中使用cmd命令注销登录用户
    SQLServer 分页存储过程
  • 原文地址:https://www.cnblogs.com/lcchuguo/p/5389754.html
Copyright © 2011-2022 走看看