P4929 【模板】舞蹈链(DLX)
题目背景
本题是舞蹈链模板——精确覆盖问题
题目描述
给定一个N行M列的矩阵,矩阵中每个元素要么是1,要么是0
你需要在矩阵中挑选出若干行,使得对于矩阵的每一列j,在你挑选的这些行中,有且仅有一行的第j个元素为1
输入输出格式
输入格式:
第一行两个数N,M
接下来N行,每行M个数字0或1,表示这个矩阵
输出格式:
一行输出若干个数表示答案,两个数之间用空格隔开,输出任一可行方案均可,顺序随意
若无解,输出“No Solution!”(不包含引号)
输入输出样例
3 3
0 0 1
1 0 0
0 1 0
2 1 3
3 3
1 0 1
1 1 0
0 1 1
No Solution!
说明
N,M≤500
保证矩阵中1的数量不超过5000个
代码
舞蹈链板子题,维护矩阵,用双向链表支持删除恢复(回溯)操作
已选集合列点权为1,则删除所有该列点权为1的集合。
#include<bits/stdc++.h>
using namespace std;
const int maxn=+;
int l[maxn],r[maxn],u[maxn],d[maxn];//左右上下指针,所在行列
int col[maxn],row[maxn];//所在行列
int h[maxn];//每行表头
int s[maxn];//每列点数
int ans[maxn];
int cnt;
int n,m;
inline int read()
{
int x=,f=;char ch=getchar();
while(ch<''||ch>''){if(ch=='-')f=-;ch=getchar();}
while(ch>=''&&ch<=''){x=(x<<)+(x<<)+ch-'';ch=getchar();}
return x*f;
}
void init()
{
for(int i=;i<=m;i++)
r[i]=i+,l[i]=i-,u[i]=d[i]=i;
r[m]=;
l[]=m;
cnt=m;
}
void insert(int R,int C)//行列
{
s[C]++;
row[++cnt]=R,col[cnt]=C;
u[cnt]=C,d[cnt]=d[C],u[d[cnt]]=cnt,d[C]=cnt;//双向链表实现
if(!h[R])h[R]=r[cnt]=l[cnt]=cnt;
else r[cnt]=h[R],l[cnt]=l[r[cnt]],r[l[cnt]]=cnt,l[r[cnt]]=cnt;
}
void remove(int C)
{
r[l[C]]=r[C],l[r[C]]=l[C];
for(int i=d[C];i!=C;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 C)
{
for(int i=u[C];i!=C;i=u[i])
for(int j=l[i];j!=i;j=l[j])
u[d[j]]=j,d[u[j]]=j,s[col[j]]++;
r[l[C]]=C,l[r[C]]=C;
}
void dance(int dep)
{
if(r[]==)
{
for(int i=;i<dep;i++)printf("%d ",ans[i]);
exit();
}
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[dep]=row[i];
for(int j=r[i];j!=i;j=r[j])remove(col[j]);
dance(dep+);
for(int j=l[i];j!=i;j=l[j])resume(col[j]);
}
resume(c);
}
int main()
{
n=read(),m=read();
init();
for(int i=;i<=n;i++)
for(int j=;j<=m;j++)
{
int a=read();
if(a)insert(i,j);
}
dance();
printf("No Solution!");
return ;
}
P4929 【模板】舞蹈链(DLX)的更多相关文章
- 舞蹈链 DLX
欢迎访问——该文出处-博客园-zhouzhendong 去博客园看该文章--传送门 舞蹈链是一个非常玄学的东西…… 问题模型 精确覆盖问题:在一个01矩阵中,是否可以选出一些行的集合,使得在这些行的集 ...
- luogu P4929 【模板】舞蹈链 DLX
LINK:舞蹈链 具体复杂度我也不知道 但是 搜索速度极快. 原因大概是因为 每次检索的时间少 有一定的剪枝. 花了2h大概了解了这个东西 吐槽一下题解根本看不懂 只能理解大概的想法 核心的链表不太懂 ...
- [学习笔记] 舞蹈链(DLX)入门
"在一个全集\(X\)中若干子集的集合为\(S\),精确覆盖(\(\boldsymbol{Exact~Cover}\))是指,\(S\)的子集\(S*\),满足\(X\)中的每一个元素在\( ...
- POJ3740 Easy Finding 舞蹈链 DLX
欢迎访问~原文出处——博客园-zhouzhendong 去博客园看该题解 题目 精确覆盖问题模板题 算法 DLX算法 学习DLX算法--传送门 代码 #include <cstring> ...
- P4929-[模板]舞蹈链(DLX)
正题 题目链接:https://www.luogu.com.cn/problem/P4929 题目大意 \(n*m\)的矩形有\(0/1\),要求选出若干行使得每一列有且仅有一个\(1\). 解题思路 ...
- Vijos1755 靶形数独 Sudoku NOIP2009 提高组 T4 舞蹈链 DLX
欢迎访问~原文出处——博客园-zhouzhendong 去博客园看该题解 题目(传送门) 题意概括 给出一个残缺的数独,求这个数独中所有的解法中的最大价值. 一个数独解法的价值之和为每个位置所填的数值 ...
- POJ3076 Sudoku 舞蹈链 DLX
欢迎访问~原文出处——博客园-zhouzhendong 去博客园看该题解 题目(传送门) 题意概括 给出一个残缺的16*16数独,求解. 题解 DLX + 矩阵构建 (两个传送门) 学完这个之后,再 ...
- POJ3074 Sudoku 舞蹈链 DLX
欢迎访问~原文出处——博客园-zhouzhendong 去博客园看该题解 题目(传送门) 题意概括 给出一个残缺的数独,求解. 题解 DLX + 矩阵构建 (两个传送门) 代码 #include & ...
- POJ2676 Sudoku 舞蹈链 DLX
欢迎访问~原文出处——博客园-zhouzhendong 去博客园看该题解 题目(传送门) 题意概括 给出一个残缺的数独,求解.SPJ 题解 DLX + 矩阵构建 (两个传送门) 代码 #includ ...
- 关于用舞蹈链DLX算法求解数独的解析
欢迎访问——该文出处-博客园-zhouzhendong 去博客园看该文章--传送门 描述 在做DLX算法题中,经常会做到数独类型的题目,那么,如何求解数独类型的题目?其实,学了数独的构建方法,那么DL ...
随机推荐
- hibernate.hbm.xml配置文件解析
转自:https://www.cnblogs.com/uoar/p/6670612.html 1. <!DOCTYPE hibernate-mapping PUBLIC "-//Hib ...
- Solr的学习使用之(八)facet实战
以下为统计media的数量功能,通过solrj,采用了facet方法,类似于sql的分组group by查询:这边的代码只是获取总媒体数量,其实他还有其他功能,去循环solrList的话,可以获取各个 ...
- Linux下安装Dubbox
1.Dubbox简介 Dubbox 是一个分布式服务框架,其前身是阿里巴巴开源项目Dubbo ,被国内电商及互联网项目中使用,后期阿里巴巴停止了该项目的维护,当当网便在Dubbo基础上进行优化,并继续 ...
- Codeforces917E
//#include<iostream> #include<cstring> #include<cstdlib> #include<cstdio> #i ...
- 自定义线程池的名称(ThreadPoolExecutor)
目的:有时候为了快速定位出现错误的位置,在采用线程池时我们需要自定义线程池的名称. 1.创建ThreadFactory(ThreadPoolExecutor默认采用的是DefaultThreadFac ...
- python进阶:装饰器
1.闭包 简单理解:闭包就是多层函数的嵌套,外层函数的返回值是内层函数的引用. def out_func(n): num = 100 def in_fucn(*args,**kwargs): # no ...
- C++数组读入MATLAB数据
data = rand(8, 10); fid = fopen('File.data', 'w'); if fid == - 1 error('Cannot open file for writing ...
- Anacond的介绍
Anacond的介绍 Anaconda指的是一个开源的Python发行版本,其包含了conda.Python等180多个科学包及其依赖项. 因为包含了大量的科学包,Anaconda 的下载文件比较大( ...
- vue中怎么使用vuex
做一个简单的vuex如何使用的介绍: 先安装: npm i vuex --save-dev 新建一个store文件夹, 在store文件夹中建一个index.js文件,在该文件中: i ...
- grunt教程
https://blog.csdn.net/sinat_38992528/article/details/79400595