其实Dance links只是一种数据结构,Dance links 才是一种算法。dacing links x就是一个高效的求解该类问题的算法,而这种算法,基于交叉十字循环双向

链表。下面是双向十字链表的示意图:

下面给一个使用这个算法模板的裸题:

Exact Cover

Description:

There is an N*M matrix with only 0s and 1s, (1 <= N,M <= 1000). An exact cover is a selection of rows such that every column has a 1 in exactly one of the selected rows. Try to find out the selected rows.

Sample Input:

6 7

3 1 4 7

2 1 4

3 4 5 7

3 3 5 6

4 2 3 6 7

2 2 7

Sample Output:

3 2 4 6

参考代码:

 #include<stdio.h>
#include<iostream>
using namespace std;
const int maxnode = * + ;
const int maxN = + ;
const int maxM = + ; struct DLX {
int n,m, size; //n行数,m列数,szie节点数
int U[maxnode], D[maxnode], L[maxnode], R[maxnode], Col[maxnode], Row[maxnode];
int H[maxN], S[maxM]; //H[i]第i行的第一个节点,S[j]第j列中节点的个数
int ansd, ans[maxN]; //ansd解包含的行数,ans[]解 void init(int _n, int _m) //初始化十字链表
{
n = _n;
m = _m;
for (int i = ; i <= m; i++)
{
Col[i] = i; Row[i] = ;
U[i] = D[i] = i;
L[i] = i + ; R[i] = i - ;
S[i] = ;
}
R[] = m; L[m] = ;
size = m;
for (int i = ; i <= n; i++)
H[i] = -;
}
void link(int r, int c) //在第r行、c列插入一个节点
{                  //注意,这里向下为方向
size++;
Col[size] = c;
Row[size] = r;
S[c]++;
D[size] = D[c];
U[D[c]] = size;
U[size] = c;
D[c] = size;
if (H[r] == -)
H[r] = R[size] = L[size] = size;
else
{
R[size] = R[H[r]];
L[R[H[r]]] = size;
L[size] = H[r];
R[H[r]] = size;
}
}
void remove(int c) //移除第c列及列上节点所在的行
{
L[R[c]] = L[c];
R[L[c]] = R[c];
for (int i = D[c]; i != c; i = D[i])
for (int j = L[i]; j != i ; j = L[j])
{
D[U[j]] = D[j];
U[D[j]] = U[j];
--S[Col[j]];
}
}
void resume(int c) //恢复第c列及列上节点所在的行,与remove刚好相反
{
for(int i = U[c];i != c;i = U[i])
for (int j = R[i]; j != i; j = R[j])
{
++S[Col[j]];
D[U[j]] = j;
U[D[j]] = j;
}
L[R[c]] = c;
R[L[c]] = c;
}
bool Dance(int d) //d为搜索的深度
{
if (R[] == )
{
ansd = d;
return true;
}
int c = R[];
for (int i = R[]; i != ; i = R[i])
if (S[i] < S[c])
c = i;
remove(c);
for (int i = D[c]; i != c; i = D[i]) //逐个尝试
{
ans[d] = Row[i];
for (int j = R[i]; j != i; j = R[j])
remove(Col[j]);
if (Dance(d + )) return true;
for (int j = L[i]; j != i; j = L[j])
resume(Col[j]);
}
resume(c); //这个可有可无,写只是为了完整性
return false;
}
}; DLX g;
int main()
{
int n, m; while (scanf("%d%d",&n,&m) == )
{
g.init(n, m);
for (int i = ; i <= n; i++)
{
int num, j;
scanf("%d", &num);
while (num--)
{
scanf("%d", &j);
g.link(i, j);
}
}
if (!g.Dance())
printf("NO\n");
else
{
printf("%d", g.ansd);
for (int i = ; i < g.ansd; i++)
printf(" %d", g.ans[i]);
printf("\n");
}
}
return ;
}

有什么不对的地方,多谢指教。


 

Dance links算法的更多相关文章

  1. Dancing Links算法(舞蹈链)

    原文链接:跳跃的舞者,舞蹈链(Dancing Links)算法——求解精确覆盖问题 作者:万仓一黍 出处:http://grenet.cnblogs.com/ 本文版权归作者和博客园共有,欢迎转载,但 ...

  2. HUST 1017 Exact cover dance links

    学习:请看 www.cnblogs.com/jh818012/p/3252154.html 模板题,上代码 #include<cstdio> #include<cstring> ...

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

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

  4. 浅入 dancing links x(舞蹈链算法)

    abastract:利用dancing links 解决精确覆盖问题,例如数独,n皇后问题:以及重复覆盖问题. 要学习dacning links 算法,首先要先了解该算法适用的问题,精确覆盖问题和重复 ...

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

    出处:http://www.cnblogs.com/grenet/p/3145800.html 精确覆盖问题的定义:给定一个由0-1组成的矩阵,是否能找到一个行的集合,使得集合中每一列都恰好包含一个1 ...

  6. Dancing Links初学记

    记得原来备战OI的时候,WCX大神就研究过Dancing Links算法并写了一篇blog.后来我还写了个搜索策略的小文章( http://www.cnblogs.com/pdev/p/3952279 ...

  7. [转] 舞蹈链(Dancing Links)——求解精确覆盖问题

    转载自:http://www.cnblogs.com/grenet/p/3145800.html 精确覆盖问题的定义:给定一个由0-1组成的矩阵,是否能找到一个行的集合,使得集合中每一列都恰好包含一个 ...

  8. DLX舞蹈链 hdu5046

    题意: 在N个城市选出K个城市,建飞机场(1 ≤ N ≤ 60,1 ≤ K ≤ N),N个城市给出坐标,选择这K个机场,使得从城市到距离自己最近的机场的 最大的距离 最小. 输出这个最小值. 思路: ...

  9. 【转】DCX (数独-八皇后问题)

    还没学会,先转了再说.. 出处:http://grenet.cnblogs.com/ 跳跃的舞者,舞蹈链(Dancing Links)算法--求解精确覆盖问题   精确覆盖问题的定义:给定一个由0-1 ...

随机推荐

  1. 4-3逻辑非运算符及案例 & 4-4

    创建类 LoginDemo3 这里取反 !(n%3==0) package com.imooc.operator; import java.util.Scanner; public class Log ...

  2. vue key值的重复键问题报错

    1.问题描述:在vue2.0+ 中做一个公用的评论组件,:key使用的时创建评论的时间,当加载更多的时候,会报错: Duplicate keys detected: '2019-01-24T07:15 ...

  3. ThinkPHP3.2.3学习笔记6---专题---数据分页

    http://document.thinkphp.cn/manual_3_2.html#data_page thinkphp3.2.3中分类的功能调用的文件$THINKPHP_HOME/ThinkPH ...

  4. ADO学途 four day 数据库左右连接

    数据库的多表操作 数据库用于存放用户数据,用户数据库的数据又会有不同表来存放不同类型的数据,这这是就会产生多 张表来满足需求.列如,部门表有市场部,技术部,行政部等.,子表就有员工具体信息表用来存放员 ...

  5. echarts相关属性设置(2)--折线图和柱状图的结合使用

    type:bar和line的组合 option = { { tooltip: { trigger: 'axis', axisPointer: { // type: 'shadow' }, // lab ...

  6. Codeforces 1142C(转化、凸包)

    可以变换坐标:x' = x, y' = y - x ^ 2,如此之后可得线性函数x' * b + c = y',可以发现两点连边为抛物线,而其他点都在这条线下方才满足题意,故而求一个上凸壳即可. #i ...

  7. IE_Script70:没有权限问题处理

    IE9浏览器执行JS时报"SCRIPT70:没有权限"错误. 经百度,发现原来与jQuery版本有关系,在jQuery1.9.1版本时会有此问题,升级版本即可.

  8. 23 在java中使用groovy类

    1       在java中使用groovy类 1.1  直接调用groovy类 在java中调用Groovy类,需要增加Groovy运行时到java的classpath中. pom.xml < ...

  9. Jmeter(二十三)稳定性测试后的波形图

    jmeter-plugins.org 这个网站为 JMeter 提供了一些增强型功能的插件,使用起来就像 Eclipse 装插件一样,完全做到了插件的可插拔特性.本文简要介绍如何使用这些插件让你的 J ...

  10. 判断EditText输入的字符串中是否包含有emoji表情

    我们在实际的开发中经常需要用到EditText 但是有一个不好的地方就是我们在前端用EditText输入了带有emoji表情的字符串之后 服务器是无法识别的,这就需要我们前端根据需求来决定表情的去留, ...