zoukankan      html  css  js  c++  java
  • hust 1017 dancing links 精确覆盖模板题

    最基础的dancing links的精确覆盖题目

      1 #include <iostream>
      2 #include <cstring>
      3 #include <cstdio>
      4 #include <algorithm>
      5 
      6 using namespace std;
      7 #define N 1005
      8 #define MAXN 1000100
      9 
     10 struct DLX{
     11     int n , m , size;//size表示当前dlx表中有多少个元素
     12     int ans[N] , k;//ans[]记录选取的行
     13     int U[MAXN] , D[MAXN] , L[MAXN] , R[MAXN];
     14     int row[MAXN] , col[MAXN] ; // 分别表示第 i 号节点属于第几行或者第几列
     15     int cnt_col[N];//分别表示第i行或者第i列有多少个节点
     16     int first[N]; //行上的起始指针
     17 
     18     void init(int _n , int _m)
     19     {
     20         n = _n , m = _m;
     21         size = m;
     22         for(int i=0 ; i<=m ; i++){
     23             U[i] = D[i] = i;
     24             L[i] = i-1 , R[i] = i+1;
     25         }
     26         L[0] = m , R[m] = 0;
     27         for(int i=1 ; i<=n ; i++) first[i]=-1;
     28         for(int i=1 ; i<=m ; i++) cnt_col[i] = 0;
     29        // for(int i=0 ; i<=n ; i++)  cout<<"here: "<<i<<" "<<L[i]<<" "<<R[i]<<endl;
     30     }
     31 
     32     void link(int r , int c)
     33     {
     34         ++size;
     35         //修改列上的情况
     36         D[size] = D[c] , U[D[c]] = size;
     37         U[size] = c , D[c] = size;
     38         cnt_col[c]++ , col[size] = c ;
     39 
     40         //修改行上的情况
     41         if(first[r]<0) first[r] = L[size] = R[size] = size;
     42         else{
     43             R[size] = R[first[r]] , L[R[first[r]]] = size;
     44             L[size] = first[r] , R[first[r]] = size;
     45         }
     46       //  cout<<" r: "<<r<<" c: "<<c<<" "<<size<<" "<<L[size]<<" "<<R[size]<<" "<<U[size]<<" "<<D[size]<<endl;
     47         row[size] = r;
     48     }
     49 
     50     void Remove(int c)
     51     {
     52         L[R[c]] = L[c] , R[L[c]] = R[c];
     53         for(int i=D[c] ; i!=c ; i=D[i]){
     54             for(int j=R[i] ; j!=i ; j=R[j]){
     55                 D[U[j]] = D[j] , U[D[j]] = U[j];
     56                 --cnt_col[col[j]];
     57             }
     58         }
     59     }
     60 
     61     void Resume(int c)
     62     {
     63         for(int i=U[c] ; i!=c ; i=U[i]){
     64             for(int j=L[i] ; j!=i ; j=L[j]){
     65                 U[D[j]] = D[U[j]] = j;
     66                 ++cnt_col[col[j]];
     67             }
     68         }
     69         R[L[c]] = L[R[c]] = c;
     70     }
     71 
     72     bool Dance(int d)
     73     {
     74 
     75         if(!R[0]){
     76             k = d;
     77             return true;
     78         }
     79         int st = R[0];
     80         //找到能删除最少节点的列先删除,这样递归的行的次数就会减少,提高效率
     81         for(int i=st ; i!=0 ; i=R[i]){
     82             if(cnt_col[st]>cnt_col[i])
     83                 st = i;
     84         }
     85 
     86         Remove(st);
     87         for(int i=D[st] ; i!=st ; i=D[i]){
     88             ans[d] = row[i];
     89             for(int j=R[i] ; j!=i ; j=R[j]) Remove(col[j]);
     90             if(Dance(d+1)) return true;
     91             for(int j=L[i] ; j!=i ; j=L[j]) Resume(col[j]);
     92         }
     93         Resume(st);
     94         return false;
     95     }
     96 }dlx;
     97 
     98 int main()
     99 {
    100    // freopen("a.in" , "r" , stdin);
    101     int n , m;
    102 
    103     while(~scanf("%d%d" , &n , &m))
    104     {
    105         dlx.init(n , m);
    106         for(int r=1 ; r<=n ; r++){
    107             int m , c;
    108             scanf("%d" , &m);
    109             for(int i=0 ; i<m ; i++){
    110                 scanf("%d" , &c);
    111                 dlx.link(r , c);
    112             }
    113         }
    114         bool ok = dlx.Dance(0);
    115         if(ok){
    116             printf("%d" , dlx.k);
    117             sort(dlx.ans , dlx.ans+dlx.k);
    118             for(int i=0 ; i<dlx.k ; i++) printf(" %d" , dlx.ans[i]);
    119             puts("");
    120         }
    121         else puts("NO");
    122     }
    123     return 0;
    124 }
  • 相关阅读:
    Html-Css 从入门到放弃(一)基础知识
    PHP7 学习笔记(十)会话控制
    Redis模块学习笔记(一)RediSearch简单使用
    PHP7 学习笔记(九)phpsize动态编译openssl扩展 (微信公众平台)
    Git与GitHub学习笔记(五)一次提交失败的记录
    PHP7 学习笔记(八)JetBrains PhpStorm 2017.1 x64 MySQL数据库管理工具的使用
    PHP7 学习笔记(七)如何使用zephir编译一个扩展记录
    阿里云(四)Linux 实例常用内核网络参数介绍与常见问题处理
    阿里云(三)安全组
    流媒体技术学习笔记之(十七)FFmpeg 3.3《希尔伯特》-新版本的亮点
  • 原文地址:https://www.cnblogs.com/CSU3901130321/p/4504895.html
Copyright © 2011-2022 走看看