记得原来备战OI的时候,WCX大神就研究过Dancing Links算法并写了一篇blog。后来我还写了个搜索策略的小文章( http://www.cnblogs.com/pdev/p/3952279.html )。当时理解的Dancing Links就是在搜索的时候在尽可能靠近搜索树根的地方剪枝。

其实Dancing Links的具体原意是解决精确覆盖问题:

一个N*M的矩阵,全部由0或1构成。要求在矩阵中拿出几行组成一个新矩阵,使得新矩阵中每一列都恰好有且只有一个1。求具体方案。

Reference:

http://www.cnblogs.com/grenet/p/3145800.html

eg1 : HUSTOJ  1017                          http://vjudge.net/problem/viewProblem.action?id=10702

裸的精确覆盖问题

贴一段网上找的代码….直接当模板用233333

Reference:http://www.cnblogs.com/183zyz/archive/2011/08/07/2129886.html

 /*Problem: HUST 1017   User: zyzamp
Memory: 1924 KB Time: 268 MS
Language: C++ Result: Accepted */
# include<stdio.h>
# include<string.h>
# include<time.h>
# define N
# define V
int U[V],D[V];
int L[V],R[V];
int C[V];
int H[N],S[N],mark[V];
int size,n,m,OK[N],flag;
void Link(int r,int c)
{
S[c]++;C[size]=c;
U[size]=U[c];D[U[c]]=size;
D[size]=c;U[c]=size;
if(H[r]==-) H[r]=L[size]=R[size]=size;
else
{
L[size]=L[H[r]];R[L[H[r]]]=size;
R[size]=H[r];L[H[r]]=size;
}
mark[size]=r;
size++;
}
void remove(int c)//删除列
{
int i,j;
L[R[c]]=L[c];
R[L[c]]=R[c];
for(i=D[c];i!=c;i=D[i])
{
for(j=R[i];j!=i;j=R[j])
{
U[D[j]]=U[j],D[U[j]]=D[j];
S[C[j]]--;
}
}
}
void resume(int c)
{
int i,j;
for(i=U[c];i!=c;i=U[i])
{
for(j=L[i];j!=i;j=L[j])
{
U[D[j]]=j;D[U[j]]=j;
S[C[j]]++;
}
}
L[R[c]]=c;
R[L[c]]=c;
}
void Dance(int k)
{
int i,j,Min,c;
if(!R[])
{
flag=;
printf("%d",k);
for(i=;i<k;i++)
printf(" %d",mark[OK[i]]);
printf("\n");
return;
}
for(Min=N,i=R[];i;i=R[i])
if(S[i]<Min) Min=S[i],c=i;
remove(c);//删除该列
for(i=D[c];i!=c;i=D[i])
{
OK[k]=i;
//remove(i);
for(j=R[i];j!=i;j=R[j])
remove(C[j]);
Dance(k+);
if(flag) return;
for(j=L[i];j!=i;j=L[j])
resume(C[j]);
//resume(i);
}
resume(c);
}
int main()
{
int i,j,num;
while(scanf("%d%d",&n,&m)!=EOF)
{
for(i=;i<=m;i++)
{
S[i]=;
D[i]=U[i]=i;
L[i+]=i;R[i]=i+;
}R[m]=;
size=m+;
memset(H,-,sizeof(H));
memset(mark,,sizeof(mark));
for(i=;i<=n;i++)
{
scanf("%d",&num);
while(num--)
{
scanf("%d",&j);
Link(i,j);
}
}
flag=;
Dance();
if(!flag) printf("NO\n");
}
return ;
}

基本结构:双向十字链表

如图对矩阵中每个元素标号:(见红色字)

像普通的双向链表中的p[i].left、p[i].right一样给每个元素设置指向四个方向的指针

例如上图中对于13有U[13]=12,D[13]=9,L[13]=15,R[13]=14

H[1….n]:每一行第一个1的标号

S[1….m]:每一列中1的个数

运行过程如下:

未完待续~

Dancing Links初学记的更多相关文章

  1. 【转】Dancing Links精确覆盖问题

    原文链接:http://sqybi.com/works/dlxcn/ (只转载过来一部分,全文请看原文,感觉讲得很好~)正文    精确覆盖问题    解决精确覆盖问题    舞蹈步骤    效率分析 ...

  2. 算法帖——用舞蹈链算法(Dancing Links)求解俄罗斯方块覆盖问题

    问题的提出:如下图,用13块俄罗斯方块覆盖8*8的正方形.如何用计算机求解? 解决这类问题的方法不一而足,然而核心思想都是穷举法,不同的方法仅仅是对穷举法进行了优化 用13块不同形状的俄罗斯方块(每个 ...

  3. Dancing Links and Exact Cover

    1. Exact Cover Problem DLX是用来解决精确覆盖问题行之有效的算法. 在讲解DLX之前,我们先了解一下什么是精确覆盖问题(Exact Cover Problem)? 1.1 Po ...

  4. 跳跃的舞者,舞蹈链(Dancing Links)算法——求解精确覆盖问题

    精确覆盖问题的定义:给定一个由0-1组成的矩阵,是否能找到一个行的集合,使得集合中每一列都恰好包含一个1 例如:如下的矩阵 就包含了这样一个集合(第1.4.5行) 如何利用给定的矩阵求出相应的行的集合 ...

  5. ZOJ 3209 Treasure Map (Dancing Links)

    Treasure Map Time Limit: 2 Seconds      Memory Limit: 32768 KB Your boss once had got many copies of ...

  6. HUST 1017 - Exact cover (Dancing Links 模板题)

    1017 - Exact cover 时间限制:15秒 内存限制:128兆 自定评测 5584 次提交 2975 次通过 题目描述 There is an N*M matrix with only 0 ...

  7. Dancing Links

    Dancing Links用来解决如下精确匹配的问题: 选择若干行使得每一列恰好有一个1.Dancing Links通过对非零元素建立双向十字循环链表.上面的例子建立的链表如下所示: 计算的时候使用搜 ...

  8. 【转】Dancing Links题集

    转自:http://blog.csdn.net/shahdza/article/details/7986037 POJ3740 Easy Finding [精确覆盖基础题]HUST1017 Exact ...

  9. POJ 3074 Sudoku (Dancing Links)

    传送门:http://poj.org/problem?id=3074 DLX 数独的9*9的模板题. 具体建模详见下面这篇论文.其中9*9的数独怎么转化到精确覆盖问题,以及相关矩阵行列的定义都在下文中 ...

随机推荐

  1. AS3声音录音

    MicRecorder, a tiny microphone library http://www.bytearray.org/?p=1858

  2. maven总结4

     仓库.nexus 构件:在maven中,任何一个依赖(jar包).插件(maven-compiler-plugin-2.5.1.jar)或者项目输出(前面例子中运行mvn clean install ...

  3. Xcode视图调试

    视图调试 使用视图调试器检查您的视图层次结构,可以轻松地判断视图位置.大小以及实现问题. 在XCode中运行你的应用程序,在调试栏上点击“调试视图层次”按钮,进入视图调试器. XCode停止你的应用程 ...

  4. VFS分析(一)挂载(持续更新)

    基础知识在<深入linux内核架构>第8章,自行脑补. 看下几个关键的过程: do_add_mount里有重要函数lock_mount, lock_mount函数的输入是struct pa ...

  5. 022医疗项目-模块二:药品目录的导入导出-对XSSF导出excel类进行封装

    资源全部来源于传智播客. 好的架构师写的程序,就算给刚入门的新手看,新手一看就知道怎么去用.所以我们要对XSSF导出excel类进行封装.这是架构师的工作,但我们也要知道. 我们写一个封装类: 这个类 ...

  6. U3D prefab

    1,prefab相当于一个类,字面意思就是预设,预先设计好的类.把一个prefab拖放到场景中就生成了一个实例,把二个prefab放到场景中就生成了两个实例. 不同的实例独立动作,拥有自己独立的状态与 ...

  7. python数字图像处理(2):图像的读取、显示与保存

    skimage提供了io模块,顾名思义,这个模块是用来图片输入输出操作的.为了方便练习,也提供一个data模块,里面嵌套了一些示例图片,我们可以直接使用. 引入skimage模块可用: from sk ...

  8. Java运算符优先级

    序列号 符号 名称 结合性(与操作数) 目数 说明 1 . 点 从左到右 双目 ( ) 圆括号 从左到右   [ ] 方括号 从左到右   2 + 正号 从右到左 单目 - 负号 从右到左 单目 ++ ...

  9. 讲述一下自己在linux中配置ftp服务的经历

    本人大二小白一名,从大一下学期就开始接触到linux,当时看到学校每次让我们下载资源都在一个ftp服务器中,感觉特别的高大上,所以自己就想什么时候自己能够拥有自己的ftp服务器,自己放一点东西进去,让 ...

  10. win7 多点触摸USB的触摸屏

    USB.C 读取bCommon判断执行哪个动作 if (bCommon & rbRSUINT)//0x02 // Handle Resume interrupt { Usb_Resume(); ...