P4929-[模板]舞蹈链(DLX)
正题
题目链接:https://www.luogu.com.cn/problem/P4929
题目大意
\(n*m\)的矩形有\(0/1\),要求选出若干行使得每一列有且仅有一个\(1\)。
解题思路
精确覆盖问题指的是一个集合\(S\)和它的若干个子集集合\(T\),要求选出\(T\)的一个子集使得里面的集合元素刚好覆盖集合\(S\)。
\(DLX\)全称是\(dancing\ link\ X\),其中\(dancing\ link\)是指交叉十字循环双向链,\(X\)是指暴搜。
知道了这些,就可以去看洛谷题解了(
code
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int N=10100;
int n,m,cnt,l[N],r[N],u[N],d[N],h[N],row[N],col[N],s[N],ans[N];
void init(){
for(int i=0;i<=m;i++)
l[i]=i-1,r[i]=i+1,u[i]=d[i]=i;
l[0]=m;r[m]=0;cnt=m;
}
void link(int x,int y){
col[++cnt]=y;s[y]++;
d[cnt]=y;u[cnt]=u[y];
d[u[y]]=cnt;u[y]=cnt;
row[cnt]=x;
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;
}
return;
}
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]]--;
return;
}
void recover(int x){
for(int i=u[x];i!=x;i=u[i])
for(int j=l[i];j!=i;j=l[j])
u[d[j]]=d[u[j]]=j,s[col[j]]++;
r[l[x]]=l[r[x]]=x;
return;
}
bool dance(int dep){
if(r[0]==0){
for(int i=0;i<dep;i++)
printf("%d ",ans[i]);
return 1;
}
int c=r[0];
for(int i=c;i!=0;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]);
if(dance(dep+1))return 1;
for(int j=l[i];j!=i;j=l[j])recover(col[j]);
}
recover(c);
return 0;
}
int main()
{
scanf("%d%d",&n,&m);
init();
for(int i=1;i<=n;i++)
for(int j=1;j<=m;j++){
int x;scanf("%d",&x);
if(x)link(i,j);
}
if(!dance(0))
puts("No Solution!");
return 0;
}
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> ...
- 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 ...
随机推荐
- 在ASP.NET Core调用WebService
一.前言 现实生产中,有一些比较老的系统对外提供的接口都是WebService形式的,如果是使用.NET Framework创建的项目调用WebService非常方便,网上有很多代码示例,这里不在讲解 ...
- Socket编程 Tcp和粘包
大多数程序员都要接触网络编程,Web开发天天和http打交道.稍微底层一点的程序员,就是TCP/UDP . 对程序员来说,Tcp/udp的核心是Socket编程. 我的浅薄的观点---------理解 ...
- webapp网络定位
1 <script> 2 var x=document.getElementById("demo"); 3 function getLocation() 4 { 5 i ...
- 二 MongoDB数据类型和$type操作符
一.MongoDB中可以使用的类型如下表所示 二.$type操作符 举个例子:想获取指定集合中title为String类型的所有文档
- jQuery中的表单对象属性过滤选择器(四、八)::enabled、:disabled、:checked、:selected
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> <html> <hea ...
- 手写个jsonp
原生jsonp具体实现 先上代码: //http://www.baidu.com?aa=11&callback=my_jsonp04349289664328899 var jsonp = fu ...
- Linux下cat命令的使用
1.普通用法-->查看文件内容 cat file_name 查看文件时的相关参数: 1.cat f1.txt,查看f1.txt文件的内容. 2.cat -n f1.txt,查看f1.txt文件的 ...
- 简单内存池的C实现
1. 序言 对于程序开发人员来说,会经常听到这种"池"的概念,例如"进程池","线程池","内存池"等,虽然很多时没有吃 ...
- shell脚本中的多行注释
shell 中注释的使用方法 1. 单行注释 单行注释最为常见,它是通过一个'#'来实现的.注意shell脚本的最开始部分"#!/bin/bash"的#号不是用来注释的. 2. 多 ...
- SVN无法查看最近日志和提交记录
现象: 使用SVN查看最近的提交记录日志时,最近总是无法显示出全部的日志内容,只能显示到几天之前的日志.就算是自己刚提交的代码也是无法没有记录的. 解决方式:右键选择TortoiseSVN中的&quo ...