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的更多相关文章

  1. 算法帖——用舞蹈链算法(Dancing Links)求解俄罗斯方块覆盖问题

    问题的提出:如下图,用13块俄罗斯方块覆盖8*8的正方形.如何用计算机求解? 解决这类问题的方法不一而足,然而核心思想都是穷举法,不同的方法仅仅是对穷举法进行了优化 用13块不同形状的俄罗斯方块(每个 ...

  2. Dancing Links X 学习笔记

    \(\\\) Definitions 双向链表:记录前后两个指针的链表,每个顺序关系都有双向的指针维护. \(Dancing\ Links\):双向十字循环链表,建立在二维关系上,每个元素记录上下左右 ...

  3. 跳跃的舞者,舞蹈链(Dancing Links)算法——求解精确覆盖问题

    精确覆盖问题的定义:给定一个由0-1组成的矩阵,是否能找到一个行的集合,使得集合中每一列都恰好包含一个1 例如:如下的矩阵 就包含了这样一个集合(第1.4.5行) 如何利用给定的矩阵求出相应的行的集合 ...

  4. 算法实践——舞蹈链(Dancing Links)算法求解数独

    在“跳跃的舞者,舞蹈链(Dancing Links)算法——求解精确覆盖问题”一文中介绍了舞蹈链(Dancing Links)算法求解精确覆盖问题. 本文介绍该算法的实际运用,利用舞蹈链(Dancin ...

  5. 浅入 dancing links x(舞蹈链算法)

    abastract:利用dancing links 解决精确覆盖问题,例如数独,n皇后问题:以及重复覆盖问题. 要学习dacning links 算法,首先要先了解该算法适用的问题,精确覆盖问题和重复 ...

  6. Dancing Links算法(舞蹈链)

    原文链接:跳跃的舞者,舞蹈链(Dancing Links)算法——求解精确覆盖问题 作者:万仓一黍 出处:http://grenet.cnblogs.com/ 本文版权归作者和博客园共有,欢迎转载,但 ...

  7. 转载 - 算法实践——舞蹈链(Dancing Links)算法求解数独

    出处:http://www.cnblogs.com/grenet/p/3163550.html 在“跳跃的舞者,舞蹈链(Dancing Links)算法——求解精确覆盖问题”一文中介绍了舞蹈链(Dan ...

  8. 转载 - 跳跃的舞者,舞蹈链(Dancing Links)算法——求解精确覆盖问题

    出处:http://www.cnblogs.com/grenet/p/3145800.html 精确覆盖问题的定义:给定一个由0-1组成的矩阵,是否能找到一个行的集合,使得集合中每一列都恰好包含一个1 ...

  9. [HDU1017]Exact cover[DLX][Dancing Links详解][注释例程学习法]

    Dancing Links解决Exact Cover问题. 用到了循环双向十字链表. dfs. 论文一知半解地看了一遍,搜出一篇AC的源码,用注释的方法帮助理解. HIT ACM 感谢源码po主.链接 ...

  10. Dancing Links 学习笔记

    Dancing Links 本周的AI引论作业布置了一道数独 加了奇怪剪枝仍然TLE的Candy?不得不去学了dlx dlxnb! Exact cover 设全集X,X的若干子集的集合为S.精确覆盖是 ...

随机推荐

  1. 拯救SQL Server数据库事务日志文件损坏的终极大招

    拯救SQL Server数据库事务日志文件损坏的终极大招 在数据库的日常管理中,我们不可避免的会遇到服务器突然断电(没有进行电源冗余),服务器故障或者 SQL Server 服务突然停掉, 头大的是l ...

  2. TypeScript 学习笔记 — 交叉类型、条件类型和条件分发(八)

    目录 交叉类型 条件类型 1. 直接传入判断的条件 2. 把条件当成泛型传入 3. 多重条件判断 4. 判断接口中的类型 extends 父子关系(类型等级) 条件分发机制 实际开发中如何避免? &l ...

  3. oeasy教您玩转vim - 73 - # 映射map

    ​ 映射map 回忆上次缩写的细节 这次了解到了:abbrivate缩写 可以定义缩写 :ab o1z oeasy 这里面还可以包括方向键.回车键之类的东西 可以定义到指定的模式 iab cab 查看 ...

  4. C练习_1005

    题自:题目 1009: [编程入门]数字的处理与判断_C语言网 题目描述 给出一个不多于5位的整数,要求 1.求出它是几位数 2.分别输出每一位数字 3.按逆序输出各位数字,例如原数为321,应输出1 ...

  5. Python 函数中箭头 (->)的用处

    Python 3 -> 是函数注释的一部分,表示函数返回值的类型. def useful_function(x) -> int: # Useful code, using x, here ...

  6. Asp .Net Core 系列:详解授权以及实现角色、策略、自定义三种授权和自定义响应

    什么是授权(Authorization)? 在 ASP.NET Core 中,授权(Authorization)是控制对应用资源的访问的过程.它决定了哪些用户或用户组可以访问特定的资源或执行特定的操作 ...

  7. 《最新出炉》系列初窥篇-Python+Playwright自动化测试-61 - 隐藏元素定位与操作

    1.简介 对于前端隐藏元素,一直是自动化定位元素的隐形杀手,让人防不胜防.脚本跑到隐藏元素时位置时报各种各样的错误,可是这种隐藏的下拉菜单又没有办法避免,所以非常头痛,这一篇只为交流隐藏元素自动化定位 ...

  8. 【微信小程序】 列表查询功能

    对应本地生活案例: https://www.bilibili.com/video/BV1834y1676P?p=52 HTML代码部分: 就是普通的wx-for指令遍历 <!--pages/cl ...

  9. 【OracleDB】 04 DDL

    Create 创建表 创建数据表,语法和MySQL基本一样 演示案例练习: 打开PLSQL,新建一个SQL脚本窗口 编写SQL语句 -- 创建学生信息表 CREATE TABLE tb_student ...

  10. 什么是MMU

    一.MMU的定义   MMU是Memory Management Unit的缩写,中文名是内存管理单元,有时也称作分页内存管理单元(Paged Memory Management Unit,缩写为PM ...