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     }
原文地址:https://www.cnblogs.com/henserlinda/p/5728786.html