luogu P4929 【模板】舞蹈链 DLX
LINK:舞蹈链
具体复杂度我也不知道 但是 搜索速度极快.
原因大概是因为 每次检索的时间少 有一定的剪枝.
花了2h大概了解了这个东西 吐槽一下题解根本看不懂 只能理解大概的想法 核心的链表不太懂.
于是直接看代码了 应该算是把代码给理解了 于是就懂了链表是怎么操作的。
首先 对于列先建立一个循环链表 r[0]==0时 说明所有的列被填完.
没必要建立0的点 因为没有什么用 只需要知道1在哪即可。
对于1的结点新建结点 然后这些结点组成一个双向十字链表 注意和上面那个循环链表不连在一起.
这个循环链表容易建立 值得一提的是需要检索列的链表 所以需要在列的链表头处加一个标号 使得能够找到.
而横排则不需要 直接利用列就可以找到.
下面是删除.
找到一列之后 随便找一行 删除当前行 同时意味着 当前行上所有1的位置所在列被删掉.
考虑删掉列的操作 这些列所在的行要被删掉 所以再枚举行 删掉列.
回溯的时候 也很容易还原.
这样进行搜索即可.
理解海星 下次再加深理解好了.
const int MAXN=5510;
int n,m,cnt,ans;
int ans1[MAXN];
int l[MAXN],r[MAXN],col[MAXN],row[MAXN],u[MAXN],d[MAXN],h[MAXN],s[MAXN];
inline void prepare()
{
rep(0,m,i)
{
r[i]=i+1;
l[i]=i-1;
u[i]=d[i]=i;
}
r[m]=0;l[0]=m;
memset(h,-1,sizeof(h));
memset(s,0,sizeof(s));
cnt=m+1;
}
inline void Link(int x,int y)
{
++s[y];//某一列的结点个数.
row[cnt]=x;col[cnt]=y;
u[cnt]=y;d[cnt]=d[y];//显然这个地方是纵向循环链表.
u[d[y]]=cnt;d[y]=cnt;
if(h[x]==-1)h[x]=r[cnt]=l[cnt]=cnt;
else
{
r[cnt]=h[x];//显然这个地方是横向循环链表.
l[cnt]=l[h[x]];//容易得到h[x]表示当前行的首结点 同时也是末结点.
r[l[h[x]]]=cnt;
l[h[x]]=cnt;
}
++cnt;
}
inline void remove(int y)
{
r[l[y]]=r[y];l[r[y]]=l[y];
for(int i=d[y];i!=y;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]];
}
}
}
inline void resume(int y)
{
for(int i=u[y];i!=y;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[y]]=y;l[r[y]]=y;
}
inline void dance(int dep)
{
if(r[0]==0)
{
rep(1,dep-1,i)put_(ans1[i]);
exit(0);
}
int y=r[0];
for(int i=r[0];i;i=r[i])if(s[i]<s[y])y=i;
remove(y);
for(int i=d[y];i!=y;i=d[i])
{
ans1[dep]=row[i];
for(int j=r[i];j!=i;j=r[j])remove(col[j]);
dance(dep+1);
for(int j=l[i];j!=i;j=l[j])resume(col[j]);
}
resume(y);
}
int main()
{
freopen("1.in","r",stdin);
get(n);get(m);prepare();
rep(1,n,i)
{
rep(1,m,j)
{
int get(op);
if(op)Link(i,j);
}
}
dance(1);puts("No Solution!");
return 0;
}
luogu P4929 【模板】舞蹈链 DLX的更多相关文章
- 舞蹈链 DLX
欢迎访问——该文出处-博客园-zhouzhendong 去博客园看该文章--传送门 舞蹈链是一个非常玄学的东西…… 问题模型 精确覆盖问题:在一个01矩阵中,是否可以选出一些行的集合,使得在这些行的集 ...
- [luogu P3384] [模板]树链剖分
[luogu P3384] [模板]树链剖分 题目描述 如题,已知一棵包含N个结点的树(连通且无环),每个节点上包含一个数值,需要支持以下操作: 操作1: 格式: 1 x y z 表示将树从x到y结点 ...
- [学习笔记] 舞蹈链(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 ...
随机推荐
- 10 个独特的 CSS 背景视觉效果
这几年的web设计中,大背景的设计变得越来越流行.特别是在现在大屏大行其道的情况下,设计师在设计中越来越多的使用大分辨率的背景图来填充屏幕,这样更能制造独特的视觉效果,能更好的传达他们想要向用户传达的 ...
- python入门005
垃圾回收机制详解(了解) 1.引用计数 x = 10 # 直接引用 print(id(x)) y = x z = x l = ['a', 'b', x] # 间接引用 print(id(l[2])) ...
- element-ui的upload组件的clearFiles方法的调用
element-ui使用中碰到的问题 <template> <div> <el-button @click="clearFiles">重新上传& ...
- requests接口自动化9-共享session和传递cookie
前言: session:用requests.session()创建会话,可以将会话信息传递给其他接口 cookie:用RequestsCookieJar或者cookie字典传递cookie信息 fil ...
- 爬虫01 /jupyter、爬虫概述、requests基本使用
爬虫02 /jupyter.爬虫概述.requests基本使用 目录 爬虫02 /jupyter.爬虫概述.requests基本使用 1. jupyter的基本使用 2. 爬虫概述 3. reques ...
- bzoj3211花神游历各国&&bzoj3038上帝造题的七分钟2*
bzoj3211花神游历各国 题意: n个数的序列,m个操作,操作两种:区间开根(向下取整)和区间求和.n≤100000,m≤200000,序列中的数非负且≤109. 题解: 一个≤109的数开6次根 ...
- Guava集合--Immutable(不可变)集合
所谓不可变集合,顾名思义就是定义了之后不可修改的集合. 一.为什么要使用不可变集合 不可变对象有很多优点,包括: 当对象被不可信的库调用时,不可变形式是安全的: 不可变对象被多个线程调用时,不存在竞态 ...
- 循序渐进VUE+Element 前端应用开发(17)--- 菜单资源管理
在权限管理系统中,菜单也属于权限控制的一个资源,应该直接应用于角色,和权限功能点一样,属于角色控制的一环.不同角色用户,登录系统后,出现的系统菜单是不同的.在VUE+Element 前端中,我们菜单结 ...
- .NET 开源项目 StreamJsonRpc 介绍[下篇]
阅读本文大概需要 9 分钟. 大家好,这是 .NET 开源项目 StreamJsonRpc 介绍的最后一篇.上篇介绍了一些预备知识,包括 JSON-RPC 协议介绍,StreamJsonRpc 是一个 ...
- 通过PHP工具箱-站点域名管理(创建本地虚拟主机)
工具:php程序员工具箱(网上很多请自己搜索下载) 1.点击其它选项菜单 -> 选择站点域名管理.如下图 2.进入站点域名管理.如下图(初始的时候,站点为空) 3.设置站点管理.如下图 网站域名 ...