舞蹈链--求精密覆盖(数据结构)

额。

第一次把博文看完,感觉之前有点懒呀。。

尊重原作者,送上链接一份。(http://www.cnblogs.com/grenet/p/3145800.html)

再往下是bin神的模板。

 

  1 /* ***********************************************
  2 Author        :kuangbin
  3 Created Time  :2014/5/25 22:55:25
  4 File Name     :E:\2014ACM\专题学习\DLX\HUST1017.cpp
  5 ************************************************ */
  6 
  7 #include <stdio.h>
  8 #include <string.h>
  9 #include <iostream>
 10 #include <algorithm>
 11 #include <vector>
 12 #include <queue>
 13 #include <set>
 14 #include <map>
 15 #include <string>
 16 #include <math.h>
 17 #include <stdlib.h>
 18 #include <time.h>
 19 using namespace std;
 20 const int maxnode = 100010;
 21 const int MaxM = 1010;
 22 const int MaxN = 1010;
 23 struct DLX
 24 {
 25     int n,m,size;
 26     int U[maxnode],D[maxnode],R[maxnode],L[maxnode],Row[maxnode],Col[maxnode];
 27     int H[MaxN], S[MaxM];
 28     int ansd, ans[MaxN];
 29     void init(int _n,int _m)
 30     {
 31         n = _n;
 32         m = _m;
 33         for(int i = 0;i <= m;i++)
 34         {
 35             S[i] = 0;
 36             U[i] = D[i] = i;
 37             L[i] = i-1;
 38             R[i] = i+1;
 39         }
 40         R[m] = 0; L[0] = m;
 41         size = m;
 42         for(int i = 1;i <= n;i++)
 43             H[i] = -1;
 44     }
 45     void Link(int r,int c)
 46     {
 47         ++S[Col[++size]=c];
 48         Row[size] = r;
 49         D[size] = D[c];
 50         U[D[c]] = size;
 51         U[size] = c;
 52         D[c] = size;
 53         if(H[r] < 0)H[r] = L[size] = R[size] = size;
 54         else
 55         {
 56             R[size] = R[H[r]];
 57             L[R[H[r]]] = size;
 58             L[size] = H[r];
 59             R[H[r]] = size;
 60         }
 61     }
 62     void remove(int c)
 63     {
 64         L[R[c]] = L[c]; R[L[c]] = R[c];
 65         for(int i = D[c];i != c;i = D[i])
 66             for(int j = R[i];j != i;j = R[j])
 67             {
 68                 U[D[j]] = U[j];
 69                 D[U[j]] = D[j];
 70                 --S[Col[j]];
 71             }
 72     }
 73     void resume(int c)
 74     {
 75         for(int i = U[c];i != c;i = U[i])
 76             for(int j = L[i];j != i;j = L[j])
 77                 ++S[Col[U[D[j]]=D[U[j]]=j]];
 78         L[R[c]] = R[L[c]] = c;
 79     }
 80     //d为递归深度
 81     bool Dance(int d)
 82     {
 83         if(R[0] == 0)
 84         {
 85             ansd = d;
 86             return true;
 87         }
 88         int c = R[0];
 89         for(int i = R[0];i != 0;i = R[i])
 90             if(S[i] < S[c])
 91                 c = i;
 92         remove(c);
 93         for(int i = D[c];i != c;i = D[i])
 94         {
 95             ans[d] = Row[i];
 96             for(int j = R[i]; j != i;j = R[j])remove(Col[j]);
 97             if(Dance(d+1))return true;
 98             for(int j = L[i]; j != i;j = L[j])resume(Col[j]);
 99         }
100         resume(c);
101         return false;
102     }
103 };
104 
105 DLX g;
106 int main()
107 {
108     //freopen("in.txt","r",stdin);
109     //freopen("out.txt","w",stdout);
110     int n,m;
111     while(scanf("%d%d",&n,&m) == 2)
112     {
113         g.init(n,m);
114         for(int i = 1;i <= n;i++)
115         {
116             int num,j;
117             scanf("%d",&num);
118             while(num--)
119             {
120                 scanf("%d",&j);
121                 g.Link(i,j);
122             }
123         }
124         if(!g.Dance(0))printf("NO\n");
125         else
126         {
127             printf("%d",g.ansd);
128             for(int i = 0;i < g.ansd;i++)
129                 printf(" %d",g.ans[i]);
130             printf("\n");
131         }
132     }
133     return 0;
134 }

 

你可能感兴趣的:(舞蹈链--求精密覆盖(数据结构))