题目背景

本题是舞蹈链模板——精确覆盖问题

题目描述

给定一个N行M列的矩阵,矩阵中每个元素要么是1,要么是0

你需要在矩阵中挑选出若干行,使得对于矩阵的每一列j,在你挑选的这些行中,有且仅有一行的第j个元素为1

输入输出格式

输入格式:

第一行两个数N,M

接下来N行,每行M个数字0或1,表示这个矩阵

输出格式:

一行输出若干个数表示答案,两个数之间用空格隔开,输出任一可行方案均可,顺序随意

若无解,输出“No Solution!”(不包含引号)

输入输出样例

输入样例#1:

3 3
0 0 1
1 0 0
0 1 0
输出样例#1:

2 1 3
输入样例#2:

3 3
1 0 1
1 1 0
0 1 1
输出样例#2:

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

  1. 舞蹈链 DLX

    欢迎访问——该文出处-博客园-zhouzhendong 去博客园看该文章--传送门 舞蹈链是一个非常玄学的东西…… 问题模型 精确覆盖问题:在一个01矩阵中,是否可以选出一些行的集合,使得在这些行的集 ...

  2. luogu P4929 【模板】舞蹈链 DLX

    LINK:舞蹈链 具体复杂度我也不知道 但是 搜索速度极快. 原因大概是因为 每次检索的时间少 有一定的剪枝. 花了2h大概了解了这个东西 吐槽一下题解根本看不懂 只能理解大概的想法 核心的链表不太懂 ...

  3. [学习笔记] 舞蹈链(DLX)入门

    "在一个全集\(X\)中若干子集的集合为\(S\),精确覆盖(\(\boldsymbol{Exact~Cover}\))是指,\(S\)的子集\(S*\),满足\(X\)中的每一个元素在\( ...

  4. POJ3740 Easy Finding 舞蹈链 DLX

    欢迎访问~原文出处——博客园-zhouzhendong 去博客园看该题解 题目 精确覆盖问题模板题 算法 DLX算法 学习DLX算法--传送门 代码 #include <cstring> ...

  5. P4929-[模板]舞蹈链(DLX)

    正题 题目链接:https://www.luogu.com.cn/problem/P4929 题目大意 \(n*m\)的矩形有\(0/1\),要求选出若干行使得每一列有且仅有一个\(1\). 解题思路 ...

  6. Vijos1755 靶形数独 Sudoku NOIP2009 提高组 T4 舞蹈链 DLX

    欢迎访问~原文出处——博客园-zhouzhendong 去博客园看该题解 题目(传送门) 题意概括 给出一个残缺的数独,求这个数独中所有的解法中的最大价值. 一个数独解法的价值之和为每个位置所填的数值 ...

  7. POJ3076 Sudoku 舞蹈链 DLX

    欢迎访问~原文出处——博客园-zhouzhendong 去博客园看该题解 题目(传送门) 题意概括 给出一个残缺的16*16数独,求解. 题解 DLX + 矩阵构建  (两个传送门) 学完这个之后,再 ...

  8. POJ3074 Sudoku 舞蹈链 DLX

    欢迎访问~原文出处——博客园-zhouzhendong 去博客园看该题解 题目(传送门) 题意概括 给出一个残缺的数独,求解. 题解 DLX + 矩阵构建  (两个传送门) 代码 #include & ...

  9. POJ2676 Sudoku 舞蹈链 DLX

    欢迎访问~原文出处——博客园-zhouzhendong 去博客园看该题解 题目(传送门) 题意概括 给出一个残缺的数独,求解.SPJ 题解 DLX + 矩阵构建  (两个传送门) 代码 #includ ...

  10. 关于用舞蹈链DLX算法求解数独的解析

    欢迎访问——该文出处-博客园-zhouzhendong 去博客园看该文章--传送门 描述 在做DLX算法题中,经常会做到数独类型的题目,那么,如何求解数独类型的题目?其实,学了数独的构建方法,那么DL ...

随机推荐

  1. const类型总结

    const 表示常类型   作用: 1.具有不可变性.   2.可以很方便对参数进行调整和修改,和宏定义一样,不变则已,变都变.   3.保护被修饰的东西,防止被意外修改.(如:在修饰函数的形参时,加 ...

  2. IC设计流程介绍

    芯片设计分为前端设计和后端设计,前端设计(也称逻辑设计)和后端设计(也称物理设计)并没有统一严格的界限,涉及到与工艺有关的设计就是后端设计. 1. 规格制定        芯片规格,也就像功能列表一样 ...

  3. leetcode 实现-168.Excel表列名称

    168.Excel表列名称 描述 给定一个正整数,返回它在 Excel 表中相对应的列名称. 例如, 1 -> A 2 -> B 3 -> C … 26 -> Z 27 -&g ...

  4. 调整notepad++的行距的方法

    notepad++是一款免费开源的文本编辑器,在windows平台上表现非常好,可以自定义的地方多,还支持主题导入,导出和切换,对各种语言的语法高亮支持也是在各大文本编辑器中名列前茅,插件库的内容也非 ...

  5. Less 混合(mixin)

    Less的混合:混合可以将一个定义好的class A轻松的引入到另一个class B中,从而简单实现class B继承class A中的所有属性.我们还可以带参数地调用,就像使用函数一样. .bord ...

  6. Linux安装mysql5.6.33

    1.下载mysql安装包: 下载地址:http://dev.mysql.com/downloads/mysql/5.6.html#downloads 下载版本:我这里选择的5.6.33,通用版,lin ...

  7. Oracle分组函数之CUBE

    功能介绍: 首先是进行无字段的聚合,然后依次对每个字段进行聚合 创建表: 插入测试数据: ROLLUP: Select t.classid,t.studentname,Sum(t.score) Fro ...

  8. Json转换 在java中的应用

    Json转换辅助类比较多,比如谷歌的Gson,阿里的FastJson,Jackson.net.sf.json等等 用了一圈后,本人还是比较推荐用net.sf.json 这里就介绍一下net.sf.js ...

  9. HDU | 1874 畅通工程续 SPFA&DIJIESITLA

    题目: 某省自从实行了很多年的畅通工程计划后,终于修建了很多路.不过路多了也不好,每次要从一个城镇到另一个城镇时,都有许多种道路方案可以选择,而某些方案要比另一些方案行走的距离要短很多.这让行人很困扰 ...

  10. 问题记录-java图片验证码显示乱码

    部署机器 操作系统:centos 7 java版本: java version "1.7.0_80" 问题症状 将一个java web的程序部署到了两台配置相同的服务器上之后(服务 ...