记得原来备战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. HTTPWatch使用

    注意:现在httpwatch也可以集成到火狐浏览器中. 一.介绍 HttpWatch是强大的网页数据分析工具.集成在Internet Explorer工具栏.包括网页摘要.Cookies管理.缓存管理 ...

  2. pycharm简单使用

    http://blog.csdn.net/chenggong2dm/article/details/9365437

  3. [转]在Ubuntu 下安装Redis 并使用init 脚本启动

    1. 下载安装:   cd /tmp wget http://redis.googlecode.com/files/redis-2.2.4.tar.gz tar -zxf redis-2.2.4.ta ...

  4. oracle学习之表空间

    一.oracle当中的dual表 注意:sql语句一定要有一个 : 结尾,不然会报错. Oracle数据库内种特殊表DualDual表Oracle实际存表任何用户均读取用没目标表SelectDual表 ...

  5. MATLAB-2015a安装

    &1 准备工作 软件和破解文件 ​软件以64位为例:链接:http://pan.baidu.com/s/1qYQQPli 密码:nc1y 解压密码:www.0daydown.com 破解文件: ...

  6. [CareerCup] 13.6 Virtual Destructor 虚析构函数

    13.6 Why does a destructor in base class need to be declared virtual? 这道题问我们为啥基类中的析构函数要定义为虚函数.首先来看下面 ...

  7. 20135316王剑桥 linux第十一周课实验笔记

    getenv函数 1.获得环境变量值的函数 2.参数是环境变量名name,例如"HOME"或者"PATH".如果环境变量存在,那么getenv函数会返回环境变量 ...

  8. CMD命令下对文件夹进行权限处理 转

    保证自己的磁盘分区格式是NTFS.FAT32是不行的. 一.Cacls.exe命令的使用 这是一个在Windows 2000/XP/Server 2003操作系统下都可以使用的命令,作用是显示或者修改 ...

  9. 【niubi-job——一个分布式的任务调度框架】----安装教程

    niubi-job是什么 niubi-job是LZ耗时三个星期,费尽心血打造的一个具备高可靠性以及水平扩展能力的分布式任务调度框架,采用quartz作为底层的任务调度管理器,zookeeper做集群的 ...

  10. servlet设置缓存时间以及文件的下载

    缓存时间的设置: public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletE ...