题目背景

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

题目描述

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

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

输入输出格式

输入格式:

第一行两个数N,M

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

输出格式:

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

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

输入输出样例

输入样例#1:

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

  1. 2 1 3
输入样例#2:

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

  1. No Solution!

说明

N,M≤500

保证矩阵中1的数量不超过5000个

代码

舞蹈链板子题,维护矩阵,用双向链表支持删除恢复(回溯)操作

已选集合列点权为1,则删除所有该列点权为1的集合。

  1. #include<bits/stdc++.h>
  2. using namespace std;
  3. const int maxn=+;
  4. int l[maxn],r[maxn],u[maxn],d[maxn];//左右上下指针,所在行列
  5. int col[maxn],row[maxn];//所在行列
  6. int h[maxn];//每行表头
  7. int s[maxn];//每列点数
  8. int ans[maxn];
  9. int cnt;
  10. int n,m;
  11. inline int read()
  12. {
  13. int x=,f=;char ch=getchar();
  14. while(ch<''||ch>''){if(ch=='-')f=-;ch=getchar();}
  15. while(ch>=''&&ch<=''){x=(x<<)+(x<<)+ch-'';ch=getchar();}
  16. return x*f;
  17. }
  18. void init()
  19. {
  20. for(int i=;i<=m;i++)
  21. r[i]=i+,l[i]=i-,u[i]=d[i]=i;
  22. r[m]=;
  23. l[]=m;
  24. cnt=m;
  25. }
  26. void insert(int R,int C)//行列
  27. {
  28. s[C]++;
  29. row[++cnt]=R,col[cnt]=C;
  30. u[cnt]=C,d[cnt]=d[C],u[d[cnt]]=cnt,d[C]=cnt;//双向链表实现
  31. if(!h[R])h[R]=r[cnt]=l[cnt]=cnt;
  32. else r[cnt]=h[R],l[cnt]=l[r[cnt]],r[l[cnt]]=cnt,l[r[cnt]]=cnt;
  33. }
  34. void remove(int C)
  35. {
  36. r[l[C]]=r[C],l[r[C]]=l[C];
  37. for(int i=d[C];i!=C;i=d[i])
  38. for(int j=r[i];j!=i;j=r[j])
  39. u[d[j]]=u[j],d[u[j]]=d[j],s[col[j]]--;
  40. }
  41. void resume(int C)
  42. {
  43. for(int i=u[C];i!=C;i=u[i])
  44. for(int j=l[i];j!=i;j=l[j])
  45. u[d[j]]=j,d[u[j]]=j,s[col[j]]++;
  46. r[l[C]]=C,l[r[C]]=C;
  47. }
  48. void dance(int dep)
  49. {
  50. if(r[]==)
  51. {
  52. for(int i=;i<dep;i++)printf("%d ",ans[i]);
  53. exit();
  54. }
  55. int c=r[];
  56. for(int i=r[];i;i=r[i])if(s[i]<s[c])c=i;//每次选择点数最小一列
  57. remove(c);
  58. for(int i=d[c];i!=c;i=d[i])
  59. {
  60. ans[dep]=row[i];
  61. for(int j=r[i];j!=i;j=r[j])remove(col[j]);
  62. dance(dep+);
  63. for(int j=l[i];j!=i;j=l[j])resume(col[j]);
  64. }
  65. resume(c);
  66. }
  67. int main()
  68. {
  69. n=read(),m=read();
  70. init();
  71. for(int i=;i<=n;i++)
  72. for(int j=;j<=m;j++)
  73. {
  74. int a=read();
  75. if(a)insert(i,j);
  76. }
  77. dance();
  78. printf("No Solution!");
  79. return ;
  80. }

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. C++内存的分区

    内存一共4个区 1.任何在函数内部声明的非static变量,其变量地址本身在栈区.栈是向低地址扩展的数据结构,即栈顶的地址和栈的最大容量是系统预先规定好的.2.任何全局变量或者静态局部变量,其变量地址 ...

  2. 13DBUtils工具类

    如果只使用JDBC进行开发,我们会发现冗余代码过多,为了简化JDBC开发,本案例我们讲采用apache commons组件一个成员:DBUtils. DBUtils就是JDBC的简化开发工具包.需要项 ...

  3. ShellExecute指定IE浏览器打开

    ShellExecute(NULL,L"open", L"iexplore.exe", L"www.baidu.com", NULL, SW ...

  4. springboot操作rabbitmq

    ////DirectExchange directExchange = new DirectExchange("test.direct");////amqpAdmin.declar ...

  5. UVa 10054 : The Necklace 【欧拉回路】

    题目链接 题目大意:我的妹妹有一串由各种颜色组成的项链. 项链中两个连续珠子的接头处共享同一个颜色. 如上图, 第一个珠子是green+red, 那么接这个珠子的必须以red开头,如图的red+whi ...

  6. React笔记01——React开发环境准备

    1 React简介 2013年由Facebook推出,代码开源,函数式编程.目前使用人数最多的前端框架.健全的文档与完善的社区. 官网:reactjs.org 阅读文档:官网中的Docs React ...

  7. Eclipse 4.9 创建springboot项目步骤

    上一篇文章写了eclipse安装STS. 现在创建Spring Starter Project  具体步骤如下: 1.等你安装好STS后,就在Eclipse >  File >New 选择 ...

  8. CF286E Ladies' Shop FFT

    题目链接 读完题后,我们发现如下性质: 在合法且和不超过 $m$ 的情况下,如果 $a_{i}$ 出现,则 $a_{i}$ 的倍数也必出现. 所以如果合法,只要对所有数两两结合一次就能得到所有 $a_ ...

  9. Integrating .NET Code and SQL Server Reporting Services

    SQL Server Reporting Services versions 2000 and 2005 (SSRS) has many powerful features. SSRS has a w ...

  10. 【转】Django-template模板语言

    Django-template模板语言 转自:https://www.cnblogs.com/zzy-9318/p/8672945.html 一.常用语法 只需要记两种特殊符号: {{  }}和 {% ...