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 ...
随机推荐
- 微信小程序开发之页面注册
页面Page是object Page({ data:{ String1 }, onLoad:function(options){ // 生命周期函数--监听页面加载 一个页面只会调用 ...
- Flutter实战视频-移动电商-65.会员中心_订单区域UI布局
65.会员中心_订单区域UI布局 我的订单区域 member.dart写我的标题的方法 布局使用瓦片布局 先做修饰,decoration颜色的背景,下边线的样式 //我的订单标题 Widget _or ...
- 参考手册(html css)
HTML CSS DOM XML DOM XML DOM Document JavaScript JavaScript RegExp JSP
- Linux系统调用及其效率
操作系统相关概念: 操作系统---管理计算机硬件与软件资源的软件,是用户与系统操作交互的接口,为在它上面运行的程序提供服务. 操作系统内核 ----操作系统的核心.负责管理系统的进程.内核.设备驱动程 ...
- 201621123016 《Java程序设计》第九周学习总结
1. 本周学习总结 1.1 以你喜欢的方式(思维导图或其他)归纳总结集合与泛型相关内容. 2. 书面作业 本次作业题集集合 1. List中指定元素的删除(题集题目) 1.1 实验总结.并回答:列举至 ...
- AtCoder Regular Contest 061 E - すぬけ君の地下鉄旅行【最短路】
具体题解又要搬大哥的了,嘿嘿~ 请点击:G点我 这道题目的难点就是同一家公司的路直接走不需要再花费,然后多了一个公司这个东西,这个不像是边的副权值(瞎说的)之类的东西,这是对于路来说的,路的属性... ...
- [Xcode 实际操作]九、实用进阶-(32)项目的打包上传和提交审核以及下架处理
目录:[Swift]Xcode实际操作 本文将演示如何将一个应用程序进行打包上传,并提交审核以及下架处理. 点击项目[DemoApp]->[Build Settings]编译设置->[Pr ...
- 【UVA - 10815】Andy's First Dictionary (set)
Andy's First Dictionary Description 不提英文了 直接上中文大意吧 XY学长刚刚立下了再不过CET就直播xx的flag,为了不真的开启直播模式,XY学长决定好好学习英 ...
- Jquery | 基础 | 事件的链式写法
$(".title").click(function () { $(this).addClass("curcol").next(".content&q ...
- iOS 同一个View识别单击和双击手势
1.给View添加手势 //view添加两个手势检测方法 self.currentPlayerView.userInteractionEnabled = YES; UITapGestureRecogn ...