标签:
基本思路(Main Thoughts):
Dancing link是一种十分优美的数据结构。
通常配合IDA*,二分等方法解决可以转化为精确覆盖和重复覆盖的题目。
精确覆盖:在一个01矩阵中选几行,使得这几行组合起来的矩阵每列有且只有一个1
重复覆盖:每列可以有多个1
实现步骤(Implementation Steps):
如果是正常的搜索
解决步骤:
DLX基本上用到的就是这种思想
辅助数组:
R,L,U,D代表当前元素在链表中右左上下的元素
C代表i点所在列
S代表i列元素个数
F,last,Last用于建表,分别是i行第一个元素,i行上一个元素,i列上一个元素。
执行步骤:
1、Dancing函数的入口
2、判断Head.Right=Head?,若是,输出答案,返回True,退出函数。
3、获得Head.Right的元素C
4、标示元素C
5、获得元素C所在列的一个元素
6、标示该元素同行的其余元素所在的列首元素
7、获得一个简化的问题,递归调用Daning函数,若返回的True,则返回True,退出函数。
8、若返回的是False,则回标该元素同行的其余元素所在的列首元素,回标的顺序和之前标示的顺序相反
9、获得元素C所在列的下一个元素,若有,跳转到步骤6
10、若没有,回标元素C,返回False,退出函数。
由于篇幅有限,在此贴出大神blog : http://www.cnblogs.com/grenet/p/3145800.html
以供大家参考。
模板(Code):
1 void build() 2 { 3 L[0]=m,R[m]=0; 4 for(int i=1;i<=m;i++) 5 { 6 R[i-1]=i; 7 L[i]=i-1; 8 c[i]=0,r[i]=i; 9 s[i]=0;d[i]=f[i]=last[i]=0; 10 } 11 } 12 13 void del(int CC) 14 { 15 L[R[CC]]=L[CC],R[L[CC]]=R[CC]; 16 for(int i=D[CC];i!=CC;i=D[i]) 17 for(int j=R[i];j!=i;j=R[j]) 18 U[D[j]]=U[j],D[U[j]]=D[j],s[c[j]]--; 19 } 20 21 void add(int CC) 22 { 23 R[L[CC]]=CC,L[R[CC]]=CC; 24 for(int i=U[CC];i!=CC;i=U[i]) 25 for(int j=L[i];j!=i;j=L[j]) 26 U[D[j]]=j,D[U[j]]=j,s[c[j]]++; 27 } 28 29 bool search(int k) 30 { 31 if(R[0]==0) 32 { 33 printf("%d",k); 34 for(int i=1;i<=k;i++) 35 printf(" %d",r[ans[i]]); 36 printf("\n"); 37 return 1; 38 } 39 int mn=999999,C; 40 for(int i=R[0];i;i=R[i]) 41 if(mn>s[i])mn=s[i],C=i; 42 del(C); 43 for(int i=D[C];i!=C;i=D[i]) 44 { 45 ans[k+1]=i; 46 for(int j=R[i];j!=i;j=R[j])del(c[j]); 47 if(search(k+1))return 1; 48 for(int j=L[i];j!=i;j=L[j])add(c[j]); 49 } 50 add(C); 51 return 0; 52 } 53 54 void link(int row,int col) 55 { 56 size++; 57 s[col]++; 58 if(!last[row])last[row]=size,R[size]=size,L[size]=size,f[row]=size; 59 else L[size]=last[row],R[last[row]]=size,last[row]=size,R[size]=f[row],L[f[row]]=size; 60 if(!d[col])d[col]=size,D[col]=size,U[size]=col,U[col]=size,D[size]=col; 61 else U[col]=size,D[size]=col,U[size]=d[col],D[d[col]]=size,d[col]=size; 62 r[size]=row,c[size]=col; 63 }
时间&空间复杂度(Time & Memory Complexity):
空间:O(?)
时间:O(?)
主要用途&优缺点(Main Applications & Advantages & Disadvantages):
主要用途: 通常配合IDA*,二分等方法解决可以转化为精确覆盖和重复覆盖的题目。
优点:快
缺点:长
推荐题目&数据(Recommendatory Problems & Data) :
Hustoj 1017 裸的精确覆盖
UVA 1603 破坏正方形 DLX重复覆盖
标签:
原文地址:http://www.cnblogs.com/tuigou/p/5052570.html