• DLX


      1     #include <iostream>
      2     #include <cstdlib>
      3     #include <cstring>
      4     #include <queue>
      5     #include <cstdio>
      6     #include <algorithm>
      7     #include <map>
      8     #define LL long long
      9 
     10     using namespace std;
     11 
     12     const int N = 2e5,M = 2e3;
     13 
     14     struct DLX
     15     {
     16         int n,m,size;
     17         int up[N],down[N],right[N],left[N],row[N],col[N]; //four pointer and the coordinate of nodes
     18         int Head[M],Size[M]; //head pointer and the size of each linkList
     19         int ans[M],ansd;
     20         void init(int _n,int _m) //initialize the head line node
     21         {
     22             n = _n;
     23             m = _m;
     24             for(int i = 0; i <= m; i++)
     25             {
     26                 Size[i] = 0;
     27                 up[i] = down[i] = i; //each column point to itself
     28                 left[i] = i-1; //row point to their neighbor
     29                 right[i] = i+1;
     30             }
     31             right[m] = 0;
     32             left[0] = m; //circulate link
     33             size = m;
     34             for(int i = 1; i <= n; i++)
     35                 Head[i] = -1;
     36         }
     37         void Link(int r,int c) //modify the four pointer
     38         {
     39             ++Size[col[++size]=c];
     40             row[size] = r;
     41             down[size] = down[c];
     42             up[down[c]] = size;
     43             up[size] = c;
     44             down[c] = size;
     45 
     46             if(Head[r] < 0) Head[r] = left[size] = right[size] = size;
     47             else
     48             {
     49                 right[size] = right[Head[r]];
     50                 left[right[Head[r]]] = size;
     51                 left[size] = Head[r];
     52                 right[Head[r]] = size;
     53             }
     54         }
     55 
     56         void remove(int c) //delete the column
     57         {
     58             left[right[c]] = left[c];
     59             right[left[c]] = right[c];
     60             for(int i = down[c]; i != c;i = down[i])
     61                 for(int j = right[i]; j != i; j = right[j])
     62             {
     63                 up[down[j]] = up[j];
     64                 down[up[j]] = down[j];
     65                 --Size[col[j]];
     66             }
     67         }
     68 
     69         void resume(int c)
     70         {
     71 
     72             for(int i = up[c]; i != c; i = up[i])
     73                 for(int j = left[i]; j != i; j = left[j])
     74             {
     75                 ++Size[col[up[down[j]]=down[up[j]]=j]];
     76             }
     77             left[right[c]] = right[left[c]] = c;
     78         }
     79 
     80         bool dance(int d) //the depth
     81         {
     82             if(right[0] == 0)
     83             {
     84                 ansd = d;
     85                 return true;
     86             }
     87 
     88             int c = right[0];
     89             for(int i = right[0]; i != 0; i = right[i])
     90             {
     91                 //if(Size[i] == 0) return false;
     92                 if(Size[i] < Size[c])
     93                     c = i;
     94             }
     95             remove(c);
     96             for(int i = down[c]; i != c; i = down[i])
     97             {
     98                 ans[d] = row[i];
     99                 for(int j = right[i]; j != i; j = right[j]) remove(col[j]);
    100                 if(dance(d+1)) return true;
    101                 for(int j = left[i]; j != i; j = left[j]) resume(col[j]);
    102             }
    103             resume(c);
    104             return false;
    105         }
    106     };
    107 
    108     DLX g;
    109 
    110     void solve(int n,int m)
    111     {
    112        // int n,m;
    113         // scanf("%d %d",&n,&m);
    114 
    115 
    116         g.init(n,m);
    117         for(int i = 1; i <= n; i++)
    118         {
    119             int t;
    120             scanf("%d",&t);
    121             for(int j = 1; j <= t; j++)
    122             {
    123                 int num;
    124                 scanf("%d",&num);
    125                 g.Link(i,num);
    126             }
    127         }
    128         if( !g.dance(0))
    129             printf("NO
    ");
    130         else
    131         {
    132             printf("%d ",g.ansd);
    133             for(int i = 0; i < g.ansd; i++)
    134             {
    135                 printf("%d%c",g.ans[i],i == g.ansd - 1?'
    ':' ');
    136             }
    137         }
    138 
    139     }
    140 
    141     int main(void)
    142     {
    143         int n,m;
    144         while(scanf("%d %d",&n,&m) != -1)
    145         {
    146             solve(n,m);
    147         }
    148         return 0;
    149     }
  • 相关阅读:
    min_25筛入门
    [湖南集训]更为厉害/谈笑风生
    [ARC060D] 最良表現
    [CQOI2007]矩形
    [SCOI2009]粉刷匠
    PAT乙级1030
    PAT乙级1028
    PAT乙级1029
    PAT乙级1026
    PAT乙级1027
  • 原文地址:https://www.cnblogs.com/henserlinda/p/5728786.html
Copyright © 2020-2023  润新知