首页 > 编程语言 >算法学习-Dancing Links X

算法学习-Dancing Links X

时间:2024-09-19 12:03:22浏览次数:1  
标签:Links Dancing int 链表 算法 col row

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;
}

标签:Links,Dancing,int,链表,算法,col,row
From: https://www.cnblogs.com/MafuyuQWQ/p/18420316

相关文章

  • 算法学习-CDQ分治
    对于二维偏序,为普通的求逆序对,只需要先排序一遍,然后树状数组或双指针即可而三位偏序甚至更高,则需要用CDQ分治,简单来说,就是将树状数组和双指针结合操作步骤如下:1.开始将数组按第一维排序,保证满足x性质2.在归并中,将左右分别按y排序,因为开始以x排序,所以保证了正确性,保证贡献从左......
  • 【算法】堆与优先级队列
    【ps】本篇有4道 leetcode OJ。目录一、算法简介二、相关例题1)最后一块石头的重量.1-题目解析.2-代码编写2)数据流中的第K大元素.1-题目解析.2-代码编写3)前K个高频单词.1-题目解析.2-代码编写4)数据流的中位数.1-题目解析.2-代码编写 一、算......
  • 多输入多输出 | Matlab实现DBO-BP蜣螂算法优化BP神经网络多输入多输出预测
    多输入多输出|Matlab实现DBO-BP蜣螂算法优化BP神经网络多输入多输出预测目录多输入多输出|Matlab实现DBO-BP蜣螂算法优化BP神经网络多输入多输出预测预测效果基本介绍程序设计往期精彩参考资料预测效果基本介绍多输入多输出|Matlab实现DBO-BP蜣螂算法优化BP神经网络多输入......
  • 一区霜冰算法+双向深度学习模型+注意力机制!RIME-BiTCN-BiGRU-Attention
    一区霜冰算法+双向深度学习模型+注意力机制!RIME-BiTCN-BiGRU-Attention目录一区霜冰算法+双向深度学习模型+注意力机制!RIME-BiTCN-BiGRU-Attention效果一览基本介绍程序设计参考资料效果一览基本介绍1.Matlab实现RIME-BiTCN-BiGRU-Attention霜冰算法优化双向时间卷积双向门控循环......
  • 顶刊算法 | Matlab实现鹈鹕算法POA-CNN-LSTM-Multihead-Attention多头注意力机制多变
    顶刊算法|Matlab实现鹈鹕算法POA-CNN-LSTM-Multihead-Attention多头注意力机制多变量时间序列预测,优化前后对比目录顶刊算法|Matlab实现鹈鹕算法POA-CNN-LSTM-Multihead-Attention多头注意力机制多变量时间序列预测,优化前后对比预测效果基本介绍程序设计参考资料预测效果基本......
  • CNN-SVM模型 | Matlab实现SO-CNN-SVM蛇群算法优化卷积神经网络结合支持向量机多特征分
    CNN-SVM模型|Matlab实现SO-CNN-SVM蛇群算法优化卷积神经网络结合支持向量机多特征分类预测目录CNN-SVM模型|Matlab实现SO-CNN-SVM蛇群算法优化卷积神经网络结合支持向量机多特征分类预测分类效果基本描述程序设计参考资料分类效果基本描述1.Matlab实现SO-CNN-SVM蛇群算法优化......
  • 【开题报告+背景+源码】基于过滤协同算法苗族银饰推荐系统的设计与实现
    项目背景与意义课题苗族银饰推荐系统,应用Java技术设计开发一个苗族银饰推荐系统,实现用户购买苗族银饰商品方便快捷,不受时间和空间的限制功能,提供用户能够更快更好地获取自己想要的苗族银饰商品推荐服务,达到向消费者提供商品推荐,帮助他们发现感兴趣的苗族银饰商品并增加购买意......
  • 基于档案演化路径的快速收敛EO多目标优化算法及其在工程设计问题中的应用
    目录1.摘要2.基于档案演化路径机制的快速收敛多目标平衡优化算法(FC‑MOEO/AEP)2.1单目标平衡优化算法EO2.2多目标平衡优化算法FC‑MOEO/AEP3.结果展示4.参考文献5.代码获取1.摘要在实际的工程优化问题中,耗时的目标函数是不可避免的。这类函数使得元启发式方法......
  • 算法:动态规划思路(仅作记录)
    以leetcode70题爬楼梯为例:假设你正在爬楼梯。需要n阶你才能到达楼顶。每次你可以爬1或2个台阶。你有多少种不同的方法可以爬到楼顶呢?递归一共两种爬楼梯的方式如果最后一步要用到方法1,那么我们得先爬到n−1,要解决的问题缩小成:从0爬到n−1有多少种不同的方法。......
  • 自动驾驶运动规划学习_碰撞检测算法_GJK
    自动驾驶运动规划学习:碰撞检测算法:GJKGilbert–Johnson–Keerthi(GJK)算法,是一种用于检测两个凸集是否重叠的高效算法,并且可以得到两个凸集的最小距离.1.4.1 GJK算法原理1.4.1.1 闵可夫斯基差(Minkowski Difference)1.4.1.3 凸性在二维空间中,如果一个凸集包含原......