Dance links算法
其实Dance links只是一种数据结构,Dance links 才是一种算法。dacing links x就是一个高效的求解该类问题的算法,而这种算法,基于交叉十字循环双向
链表。下面是双向十字链表的示意图:
下面给一个使用这个算法模板的裸题:
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算法的更多相关文章
- Dancing Links算法(舞蹈链)
原文链接:跳跃的舞者,舞蹈链(Dancing Links)算法——求解精确覆盖问题 作者:万仓一黍 出处:http://grenet.cnblogs.com/ 本文版权归作者和博客园共有,欢迎转载,但 ...
- HUST 1017 Exact cover dance links
学习:请看 www.cnblogs.com/jh818012/p/3252154.html 模板题,上代码 #include<cstdio> #include<cstring> ...
- 跳跃的舞者,舞蹈链(Dancing Links)算法——求解精确覆盖问题
精确覆盖问题的定义:给定一个由0-1组成的矩阵,是否能找到一个行的集合,使得集合中每一列都恰好包含一个1 例如:如下的矩阵 就包含了这样一个集合(第1.4.5行) 如何利用给定的矩阵求出相应的行的集合 ...
- 浅入 dancing links x(舞蹈链算法)
abastract:利用dancing links 解决精确覆盖问题,例如数独,n皇后问题:以及重复覆盖问题. 要学习dacning links 算法,首先要先了解该算法适用的问题,精确覆盖问题和重复 ...
- 转载 - 跳跃的舞者,舞蹈链(Dancing Links)算法——求解精确覆盖问题
出处:http://www.cnblogs.com/grenet/p/3145800.html 精确覆盖问题的定义:给定一个由0-1组成的矩阵,是否能找到一个行的集合,使得集合中每一列都恰好包含一个1 ...
- Dancing Links初学记
记得原来备战OI的时候,WCX大神就研究过Dancing Links算法并写了一篇blog.后来我还写了个搜索策略的小文章( http://www.cnblogs.com/pdev/p/3952279 ...
- [转] 舞蹈链(Dancing Links)——求解精确覆盖问题
转载自:http://www.cnblogs.com/grenet/p/3145800.html 精确覆盖问题的定义:给定一个由0-1组成的矩阵,是否能找到一个行的集合,使得集合中每一列都恰好包含一个 ...
- DLX舞蹈链 hdu5046
题意: 在N个城市选出K个城市,建飞机场(1 ≤ N ≤ 60,1 ≤ K ≤ N),N个城市给出坐标,选择这K个机场,使得从城市到距离自己最近的机场的 最大的距离 最小. 输出这个最小值. 思路: ...
- 【转】DCX (数独-八皇后问题)
还没学会,先转了再说.. 出处:http://grenet.cnblogs.com/ 跳跃的舞者,舞蹈链(Dancing Links)算法--求解精确覆盖问题 精确覆盖问题的定义:给定一个由0-1 ...
随机推荐
- Flutter实战视频-移动电商-44.详细页_首屏自定义Widget编写
44.详细页_首屏自定义Widget编写 把详细页的图片.标题.编号和价格形成一个单独的widget去引用 详情页的顶部单独封装个插件 在pages下面新建detials_page的文件件并在里面新建 ...
- ugui batches
先渲染非重叠,然后渲染重叠 如果两个图不是同一个图集,并且都不重叠,那么按节点挂载顺序渲染 节点挂接多复杂没关系,关键是节点在Canvas下的顺序,绑在同一节点或者全部绑在根节点Canvas下渲染 ...
- EasyUI/TopJUI可编辑表格的列根据返回数据判断是使用 combobox 还是 numberbox
这两天研究了一下topjui的可编辑表格edatagrid,想在每一列的后面根据返回的数据判断是使用 combobox 还是 numberbox,期间遇到了一些坑,下面实现代码,需要的朋友可以参考一下 ...
- IP服务-7-系统日志
默认情况下.Cisco路由器和交换机并不在NVRAM (非易失性内存)中记录事件:工程师可以使用命令logging buffered改变设备的这一默认行为.并且还可以使用额外参数来设定日志缓存的大小. ...
- Flask (七) 部署
阿里云部署Flask项目 部署Flask项目和部署Django项目基本一致,我们也使用uwsgi+nginx 我们在部署Django项目基础上部署Flask项目 1, 将uwsgi.ini ...
- 牛客寒假6-D.美食
链接:https://ac.nowcoder.com/acm/contest/332/D 题意: 小B喜欢美食. 现在有n个美食排成一排摆在小B的面前,依次编号为1..n,编号为i的食物大小为 a[i ...
- Hive_Hive的数据模型_数据存储
Hive的数据模型_数据存储 web管理工具察看HDFS文件系统:http://<IP>:50070/ 基于HDFS没有专门的数据存储格式,默认使用制表符存储结构主要包括:数据库,文件,表 ...
- [在读]web前端黑客技术揭秘
- Unity Shader入门精要学习笔记 - 第11章 让画面动起来
转自 冯乐乐的 <Unity Shader入门精要> Unity Shader 中的内置变量 动画效果往往都是把时间添加到一些变量的计算中,以便在时间变化时画面也可以随之变化.Unity ...
- Java方式配置Spring
概述 本文主要讲的是如何使用Java Bean来配置Spring,而不是用xml来配置Spring. 本文主要是代码,需要注意的都在注释里面. 代码打包下载地址(注:项目使用Maven构建) Java ...