记得原来备战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. C r and n(组合数)

    找出n个数的r个数的组合,如下形式: 输入:n,r分别为 5, 3 输出: 5    4     3 5    4     2 5    4     1 5    3     2 5    3     ...

  2. zabbix错误记录

    zabbix部署好,在使用一段时间后,出现了不少报错,在此简单做一记录.1)Zabbix监控界面报错“Lack of free swap space”解决公司线上部署的zabbix3.0的监控界面首页 ...

  3. lvm之创建/扩容/缩容/快照及关闭的全部流程操作记录

    基本介绍Linux用户安装Linux 操作系统时遇到的一个最常见的难以决定的问题就是如何正确地给评估各分区大小,以分配合适的硬盘空间.随着 Linux的逻辑盘卷管理功能的出现,这些问题都迎刃而解, l ...

  4. 28Spring_的事务管理_银行转账业务加上事务控制_基于注解进行声明式事务管理

    将applicationContext.xml 和 AccountServiceImpl 给备份一个取名为applicationContext2.xml 和 AccountServiceImpl2.j ...

  5. TabControl的SelectionChanged事件

    DataGrid作为TabControl控件的TabItem的content元素. 当操作DataGrid的不同cell时,会引发了TabControl的SelectionChanged事件的问题. ...

  6. 【MFC】序列化(Serialize)、反序列化(Deserialize)

    1.首先在头文件里面声明 DECLARE_SERIAL(CSelectionSerial) 2.重写CObject的Serialize函数 virtual void Serialize(CArchiv ...

  7. C# 单点登录 MVC

    实现sso系统的主要难点: 1:不能直接访问数据库,有安全隐患,而且还容易乱套. 2:多个系统需要进行单点登录,逻辑需要严谨,能支持N多系统.而不只是少数几个系统. 3:代码不能过于复杂,需要简洁,灵 ...

  8. 架构MVC——JS中的理论

    什么是MVC MVC是一种设计模式,它将应用划分为3个部分:数据(模型).展现层(视图)和用户交互层(控制器). 一个事件发生的过程可以描述如下: 用户和应用产生交互 控制器的事件处理器被触发 控制器 ...

  9. php基础08:改变数据类型

    <?php //1.获取数据类型 $num = 55; echo gettype($num); //integer //2.设置数据类型 settype($num, "string&q ...

  10. iBatis.Net(C#)SQL数据映射

    转载请注明 http://www.cnblogs.com/13590/archive/2013/03/01/2938126.html 摘要:本文探讨了iBatis.Net框架的XML数据映射文件各配置 ...