题目背景

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

题目描述

给定一个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. 一gradle创建SSM项目——依赖包

    build.gradle compile:编译时必须. runtime:运行时必须,包括编译时. testCompile:测试编译时必须. testRuntime:测试运行时必须,包括编译时. 注:此 ...

  2. Dubbo学习源码总结系列四--集群容错机制

    Dubbo提供了哪些集群容错机制?如何实现的?         提供了六种集群容错机制,包括Failover(失败自动切换,尝试其他服务器).Failfast(失败立即抛出异常).Failsafe(失 ...

  3. windows下zookeeper集群安装

    windows下zookeeper单机版安装,见:https://www.cnblogs.com/lbky/p/9867899.html 一:zookeeper节点为什么是奇数个? 单机模式的zk进程 ...

  4. Python---基础-运算符int和range函数

    这行代码是什么意思 if not (money<100) money >= 100 -------------------------------假设有x = 1, y = 2, z = ...

  5. Minor GC、Major GC、Full GC 区别

    原创转载请注明出处:https://www.cnblogs.com/agilestyle/p/11488036.html Minor GC 清理年轻代 Minor GC指新生代GC,即发生在新生代(包 ...

  6. Android Release 打包提示 "错误:找不到符号"

    搞了一上午....必须记录下来

  7. 探讨vue的双向绑定原理及实现

    1.vue的实现原理 vue的双向绑定是由数据劫持结合发布者-订阅者模式实现的,那么什么是数据劫持?vue是如何进行数据劫持的?说白了就是通过Object.defineProperty()来劫持对象属 ...

  8. 卷积神经网络(Text--cnn)(知识点整理)

    参考:http://www.wildml.com/2015/12/implementing-a-cnn-for-text-classification-in-tensorflow/ 独热编码(one- ...

  9. asp.net选择文件夹上传

    HTML部分 <%@PageLanguage="C#"AutoEventWireup="true"CodeBehind="index.aspx. ...

  10. Cocoapods组件化之搭建组件化项目框架

    一,概述 随着公司业务需求的不断迭代发展,工程的代码量和业务逻辑也越来越多,原始的开发模式和架构已经无法满足我们的业务发展速度了,这时我们就需要将原始项目进行一次重构大手术了.这时我们应该很清晰这次手 ...