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 ...
随机推荐
- .NET File 多图上传
HTML代码: <div> <div> <input type="file" style="display:none" id=&q ...
- JavaEE高级-Hibernate学习笔记
*什么是Hibernate? > 一个框架 > 一个Java领域的持久层框架 > 一个ORM框架 *对象的持久化 > 狭义的理解:“持久化”仅仅指把对象永久保存到数据库中 &g ...
- 02.Linux-CentOS系统Firewalld防火墙配置
1.firewalld的基本使用 启动: systemctl start firewalld关闭: systemctl stop firewalld查看状态: systemctl status fir ...
- python基础内置函数
#取绝对值 #print(abs(-1)) #对序列中的元素进行bool运算,如果可迭代对象为空也返回True # print(all((1,23,))) # print(all({"nam ...
- 函数&&变量
#*- encoding=utf-8 -*import sysprint(sys.getdefaultencoding()) def test(x,y,z): print(x) print(y) pr ...
- html+css+javascript学习记录1
<p> 最近在学一部分前端,知识点很多,却没怎么系统地应用过,因而理解可能不够深吧.所以我想做点片段似的东西,不懂的再在网上搜一搜,这样可能会更有意思点,所以做了这个记录,希望自己坚持下去 ...
- Oracle Internals Notes Redo Write Triggers
There are four conditions that cause LGWR to perform a redo write. When LGWR is idle, it sleeps on a ...
- Android keystore 密码找回
昨天准备给自己的应用发布一个新版本,在apk打包时,发现之前的用的keystore密码忘了. 蛋碎了一地,我把我所能想到的密码都试了一遍(注:我平常在各个门户网站注册基本上用的都是那几个字母和数字组合 ...
- js 通过浏览器直接打开应用程序(IOS,Android)
实现效果 如下图所示,在手机浏览器中访问京东的手机版网站(m.jd.com),顶部会有一个广告图,点击这个广告图,如果手机上已经安装了京东App,则直接打开,如果没有安装,则开始下载. 实现方式 1. ...
- centos7中yum安装lamp环境
一.准备工作 1.1 环境 操作系统:centos7(CentOS-7-x86_64-Minimal-1708) 硬件:(这个根据项目运行和配置建议设置,一般我先配个1核1G) 1.2 关闭selin ...