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;
}

最新文章

  1. layer弹出层全屏及关闭
  2. 手机页面touch触摸事件
  3. Codeforces Round #292 (Div. 1) B. Drazil and Tiles 拓扑排序
  4. ubuntu中rar与unrar用法详解
  5. 2016,除了 DevOps,企业还应该知道 CMDB!
  6. SYNONYMS
  7. Java学习——接口Interface
  8. (原)ubuntu14手动安装matplotlib1.5
  9. 关于JQuery中$.data绑定数据原理或逻辑
  10. PHP扩展memcache模
  11. hive参数配置
  12. CTSC&amp;APIO2017
  13. java基础(六)-----String性质深入解析
  14. H5 69-清除浮动方式四
  15. LeetCode107.二叉树的层次遍历II
  16. MySQL Crash Course #21# Chapter 29.30. Database Maintenance &amp; Improving Performance
  17. ARMCC中$Super$$和$Sub$$的使用
  18. ASP.NET Core 中的 Razor 页面介绍
  19. RobHess的SIFT源码分析:imgfeatures.h和imgfeatures.c文件
  20. centos svnversion安装部署

热门文章

  1. HTTP响应头拆分/CRLF注入详解
  2. Java 基础 —— Lambda 表达式
  3. Canonical通过Flutter启用Linux桌面应用程序支持
  4. Pop!_OS安装与配置(一):下载安装
  5. YAML 语言教程与使用案例
  6. 使用wsl2時碰到的問題
  7. JVM 专题六:运行时数据区(一)概述
  8. bzoj1787[Ahoi2008]Meet 紧急集合&amp;bzoj1832[AHOI2008]聚会
  9. 【运维--安全相关】cerbot证书自动化续期
  10. OSCP Learning Notes - Privilege Escalation