其实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. 妙味课堂史上最全的javascript视频教程,前端开发人员必备知识点,新手易学,拔高必备!!!

    妙味课堂是北京妙味趣学信息技术有限公司旗下的IT前端培训品牌, 妙味课堂是一支独具特色的IT培训团队,妙味反对传统IT教育枯燥乏味的教学模式,妙味提供一种全新的快乐学习方法! 妙味js视教第一部分  ...

  2. CCF 201509-3 模板生成系统 (STL+模拟)

    问题描述 成成最近在搭建一个网站,其中一些页面的部分内容来自数据库中不同的数据记录,但是页面的基本结构是相同的.例如,对于展示用户信息的页面,当用户为 Tom 时,网页的源代码是 而当用户为 Jerr ...

  3. Mac和Unix的常用命令行指令

    更新:2017/05/03/02:05 更新: 2017/05/14/11:14 更新: 2017/09/05/16:15 增加rm -rf 强制删除文件夹内所有文件 更新: 2018/01/16 完 ...

  4. 51nod - 1188 - 最大公约数之和 V2 - 数论

    https://www.51nod.com/Challenge/Problem.html#!#problemId=1188 求\(\sum\limits_{i=1}^{n-1}\sum\limits_ ...

  5. 算法学习--Day10

    今天开始了新一章的学习,前面的题目虽然做了几道,但是我觉得训练量仍然太小了.不过机试确实很多题目,并且难度也有所不同,所以要针对不同的题目进行专门的练习才好.题目类型有些多,等接下来我将搜索的题目写完 ...

  6. typescript语法入门

    一.字符串 1.多行字符串: (支持换行) ` <div></div> <p></p> ` 2.表达式:${} --> 变量 var a = 'd ...

  7. GenericKeychain

    KeychainItemWrapper是apple官方例子“GenericKeychain”里一个访问keychain常用操作的封装类,在官网上 下载了GenericKeychain项目后,只需要把“ ...

  8. 黑马MySQL数据库学习day02 表数据CRUD 约束CRUD

    /* 基础查询练习: 1.字段列表查询 当查询全部字段时,一种简便方式,使用*代替全部字段(企业中不推荐使用) 2.去除重复行 DISTINCT,注意修饰的是行,也就是整个字段列表,而不是单个字段. ...

  9. html Css PC 移动端 公用部分样式代码整理

    css常用公用部分样式代码整理: body, html, div, blockquote, img, label, p, h1, h2, h3, h4, h5, h6, pre, ul, ol, li ...

  10. 115 Distinct Subsequences 不同子序列

    给定一个字符串 S 和一个字符串 T,求 S 的不同的子序列中 T 出现的个数.一个字符串的一个子序列是指:通过删除一些(也可以不删除)字符且不干扰剩余字符相对位置所组成的新字符串.(譬如," ...