算法学习-Dancing Links X
Dancing Links X 舞蹈链。
实质为用循环十字链在图上将所有“1”的位置链起来
构造较为巧妙,且极易理解,本题为 DLX 模板(精确覆盖问题)
DLX 算法的题目做法一般为将所求方案转化为行号,将限制条件转化为列号
然后 dfs 暴力枚举,用循环十字链优化
/*
Finished at 12:14 on 2024.4.5
*/
#include <bits/stdc++.h>
using namespace std;
const int N = 510, M = 250510;
int n, m;
int a[N][N];
int row[M], col[M];
//row为每个点所在行号,col为每个点所在列号
int cnt, s[N], h[N];
//cnt为给每个链上的点的编号
//s表示某一列上所建链表点个数
//h为每一行的列表头
int u[M], d[M], l[M], r[M];
//u, d, l, r分别表示某个链表点上下左右所连的
int res[N];
//所选行号
void init() //初始化第0行的链表头
{
for (int i = 0; i <= m; i ++ )
u[i] = d[i] = i, l[i] = i - 1, r[i] = i + 1; //初始化左右,上下还没点,所以指向自己
l[0] = m, r[m] = 0, cnt = m; //处理剩下的0,m点
}
void link(int x, int y)
{
s[y] ++ ;
cnt ++ ;
row[cnt] = x, col[cnt] = y;
u[cnt] = y;
d[cnt] = d[y]; //可类比链表,正常加即可
u[d[y]] = cnt;
d[y] = cnt;
if (!h[x]) h[x] = l[cnt] = r[cnt] = cnt; //本行无链表点,则加进去
else
{
l[cnt] = l[h[x]];
r[cnt] = h[x]; //正常双向链表加
r[l[h[x]]] = cnt;
l[h[x]] = cnt;
}
}
void remove(int x)
{
r[l[x]] = r[x], l[r[x]] = l[x];
for (int i = d[x]; i != x; i = d[i]) //向下,向右删除每个点
for (int j = r[i]; j != i; j = r[j])
u[d[j]] = u[j], d[u[j]] = d[j], s[col[j]] -- ;
}
void resume(int x)
{
r[l[x]] = x, l[r[x]] = x;
for (int i = u[x]; i != x; i = u[i]) //向上,向左恢复每个点
for (int j = l[i]; j != i; j = l[j])
u[d[j]] = j, d[u[j]] = j, s[col[j]] ++ ;
}
bool dance(int depth)
{
if (r[0] == 0)
{
for (int i = 0; i < depth; i ++ ) cout << res[i] << ' ';
cout << '\n'; //第0行删完了
return true;
}
int y = r[0];
for (int i = r[0]; i; i = r[i]) //优先找1少的
if (s[y] > s[i]) y = i;
remove(y);
for (int i = d[y]; i != y; i = d[i])
{
res[depth] = row[i];
for (int j = r[i]; j != i; j = r[j]) remove(col[j]);
if (dance(depth + 1)) return true; //暴力枚举
for (int j = l[i]; j != i; j = l[j]) resume(col[j]);
}
resume(y);
return false;
}
int main()
{
cin >> n >> m;
for (int i = 1; i <= n; i ++ )
for (int j = 1; j <= m; j ++ )
cin >> a[i][j];
init();
for (int i = 1; i <= n; i ++ )
for (int j = 1; j <= m; j ++ )
if (a[i][j]) link(i, j); //1位置加点
if (!dance(0)) cout << "No Solution!\n";
return 0;
}
算法学习-Dancing Links X的更多相关文章
- 算法帖——用舞蹈链算法(Dancing Links)求解俄罗斯方块覆盖问题
问题的提出:如下图,用13块俄罗斯方块覆盖8*8的正方形.如何用计算机求解? 解决这类问题的方法不一而足,然而核心思想都是穷举法,不同的方法仅仅是对穷举法进行了优化 用13块不同形状的俄罗斯方块(每个 ...
- Dancing Links X 学习笔记
\(\\\) Definitions 双向链表:记录前后两个指针的链表,每个顺序关系都有双向的指针维护. \(Dancing\ Links\):双向十字循环链表,建立在二维关系上,每个元素记录上下左右 ...
- 跳跃的舞者,舞蹈链(Dancing Links)算法——求解精确覆盖问题
精确覆盖问题的定义:给定一个由0-1组成的矩阵,是否能找到一个行的集合,使得集合中每一列都恰好包含一个1 例如:如下的矩阵 就包含了这样一个集合(第1.4.5行) 如何利用给定的矩阵求出相应的行的集合 ...
- 算法实践——舞蹈链(Dancing Links)算法求解数独
在“跳跃的舞者,舞蹈链(Dancing Links)算法——求解精确覆盖问题”一文中介绍了舞蹈链(Dancing Links)算法求解精确覆盖问题. 本文介绍该算法的实际运用,利用舞蹈链(Dancin ...
- 浅入 dancing links x(舞蹈链算法)
abastract:利用dancing links 解决精确覆盖问题,例如数独,n皇后问题:以及重复覆盖问题. 要学习dacning links 算法,首先要先了解该算法适用的问题,精确覆盖问题和重复 ...
- Dancing Links算法(舞蹈链)
原文链接:跳跃的舞者,舞蹈链(Dancing Links)算法——求解精确覆盖问题 作者:万仓一黍 出处:http://grenet.cnblogs.com/ 本文版权归作者和博客园共有,欢迎转载,但 ...
- 转载 - 算法实践——舞蹈链(Dancing Links)算法求解数独
出处:http://www.cnblogs.com/grenet/p/3163550.html 在“跳跃的舞者,舞蹈链(Dancing Links)算法——求解精确覆盖问题”一文中介绍了舞蹈链(Dan ...
- 转载 - 跳跃的舞者,舞蹈链(Dancing Links)算法——求解精确覆盖问题
出处:http://www.cnblogs.com/grenet/p/3145800.html 精确覆盖问题的定义:给定一个由0-1组成的矩阵,是否能找到一个行的集合,使得集合中每一列都恰好包含一个1 ...
- [HDU1017]Exact cover[DLX][Dancing Links详解][注释例程学习法]
Dancing Links解决Exact Cover问题. 用到了循环双向十字链表. dfs. 论文一知半解地看了一遍,搜出一篇AC的源码,用注释的方法帮助理解. HIT ACM 感谢源码po主.链接 ...
- Dancing Links 学习笔记
Dancing Links 本周的AI引论作业布置了一道数独 加了奇怪剪枝仍然TLE的Candy?不得不去学了dlx dlxnb! Exact cover 设全集X,X的若干子集的集合为S.精确覆盖是 ...
随机推荐
- 拯救SQL Server数据库事务日志文件损坏的终极大招
拯救SQL Server数据库事务日志文件损坏的终极大招 在数据库的日常管理中,我们不可避免的会遇到服务器突然断电(没有进行电源冗余),服务器故障或者 SQL Server 服务突然停掉, 头大的是l ...
- TypeScript 学习笔记 — 交叉类型、条件类型和条件分发(八)
目录 交叉类型 条件类型 1. 直接传入判断的条件 2. 把条件当成泛型传入 3. 多重条件判断 4. 判断接口中的类型 extends 父子关系(类型等级) 条件分发机制 实际开发中如何避免? &l ...
- oeasy教您玩转vim - 73 - # 映射map
映射map 回忆上次缩写的细节 这次了解到了:abbrivate缩写 可以定义缩写 :ab o1z oeasy 这里面还可以包括方向键.回车键之类的东西 可以定义到指定的模式 iab cab 查看 ...
- C练习_1005
题自:题目 1009: [编程入门]数字的处理与判断_C语言网 题目描述 给出一个不多于5位的整数,要求 1.求出它是几位数 2.分别输出每一位数字 3.按逆序输出各位数字,例如原数为321,应输出1 ...
- Python 函数中箭头 (->)的用处
Python 3 -> 是函数注释的一部分,表示函数返回值的类型. def useful_function(x) -> int: # Useful code, using x, here ...
- Asp .Net Core 系列:详解授权以及实现角色、策略、自定义三种授权和自定义响应
什么是授权(Authorization)? 在 ASP.NET Core 中,授权(Authorization)是控制对应用资源的访问的过程.它决定了哪些用户或用户组可以访问特定的资源或执行特定的操作 ...
- 《最新出炉》系列初窥篇-Python+Playwright自动化测试-61 - 隐藏元素定位与操作
1.简介 对于前端隐藏元素,一直是自动化定位元素的隐形杀手,让人防不胜防.脚本跑到隐藏元素时位置时报各种各样的错误,可是这种隐藏的下拉菜单又没有办法避免,所以非常头痛,这一篇只为交流隐藏元素自动化定位 ...
- 【微信小程序】 列表查询功能
对应本地生活案例: https://www.bilibili.com/video/BV1834y1676P?p=52 HTML代码部分: 就是普通的wx-for指令遍历 <!--pages/cl ...
- 【OracleDB】 04 DDL
Create 创建表 创建数据表,语法和MySQL基本一样 演示案例练习: 打开PLSQL,新建一个SQL脚本窗口 编写SQL语句 -- 创建学生信息表 CREATE TABLE tb_student ...
- 什么是MMU
一.MMU的定义 MMU是Memory Management Unit的缩写,中文名是内存管理单元,有时也称作分页内存管理单元(Paged Memory Management Unit,缩写为PM ...