其实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. Xcode10更新报错:library not found for -lstdc++.6.0.9

    转载链接!:https://blog.csdn.net/timtian008/article/details/82792629 由于iPhone X Max 及iOS12系统的到来,必须升级xcode ...

  2. unity 引入 android第三方sdk

    unity中调用java代码中介绍了unity调用android java代码的一些基础.引入android开发第三方sdk的操作跟调用java代码的操作相似,只是多了一步引入第三方jar. unit ...

  3. [Xcode 实际操作]九、实用进阶-(7)使用Xcode的版本管理功能(SCM)

    目录:[Swift]Xcode实际操作 本文将演示系统的版本控制功能. 软件配置管理(SCM):Software configuration management 是指通过执行版本控制.变更控制的规程 ...

  4. IT兄弟连 JavaWeb教程 JSP内置对象经典案例

    案例需求:使用MVC模式编写一个程序当发起一个deptList.do请求时在servlet中准备一个部门列表对象,把这个列表对象放入request作用域中,然后转发到deptlist.jsp,使用js ...

  5. 笔记-JavaWeb学习之旅7

    JavaScript基础 概念:一门客户端脚本语言,运行在客户端浏览器中,每一个浏览器都有JavaScript的解析引擎,是一个脚本语言,不需要编译,直接就可以被浏览器解析执行. JavaScript ...

  6. Mybatis思

    站在巨人的肩膀上,感谢! mybatis源码分析之Mapper代理实现分析 2017年11月21日 23:39:04 huangshanchun 阅读数:277    版权声明:欢迎转载,如有不足之处 ...

  7. win10怎么修改DNS

    方法/步骤   1 鼠标右键桌面单击此电脑--属性,如下图所示 2 进入电脑属性,选择控制面板主页,如下图所示 3 我们继续选择网络和Internet进入,如下图所示 4 进入网络和Internet, ...

  8. python的正则表达式支持(链接)

    http://www.cnblogs.com/huxi/archive/2010/07/04/1771073.html

  9. Linux —— 常用命令集合

    关机和重启命令 shutdown [选项] 时间 (添加&,把关机任务放在后台执行) 只有shutdown可以保存关机时资源 操作选项 重启: r 关机: h 取消一个关机任务: c 关机命令 ...

  10. 通过API获取统计信息时报Access denied错误处理记录

    通过API获取HDFS统计信息时报Access denied错误信息,错误信息如下: org.apache.hadoop.ipc.RemoteException(org.apache.hadoop.s ...