1017 - Exact cover

Problem's Link:   http://acm.hust.edu.cn/problem/show/1017


Mean:

给定一个由0-1组成的矩阵,是否能找到一个行的集合,使得集合中每一列都恰好包含一个1

analyse:

初学DLX。

这是DLX处理的最简单的问题,也是模板题。

Time complexity: O(n*d)

Source code: 

#include <stdio.h>
#include <string.h>
#include <iostream>
#include <algorithm>
#include <vector>
#include <queue>
#include <set>
#include <map>
#include <string>
#include <math.h>
#include <stdlib.h>
#include <time.h>
using namespace std;
const int MAXNode = ;
const int MAXN = ;
struct DLX
{
int n,m,size;
int U[MAXNode],D[MAXNode],R[MAXNode],L[MAXNode],Row[MAXNode],Col[MAXNode];
int H[MAXN], S[MAXN]; // H[i]---第i行第一个为1的index S[i]---第i列为1的个数
int ansd, ans[MAXN];
void init(int _n,int _m)
{
n = _n;
m = _m;
for(int i = ;i <= m;i++) // 初始化第一行(图中的C[])
{
S[i] = ; // 第i列为1的个数
U[i] = D[i] = i;
L[i] = i-;
R[i] = i+;
}
R[m] = ; L[] = m; // 第一行的最后一个指向第一行的第一个(成环)
size = m; // 从m开始以后的都是普通结点
for(int i = ;i <= n;i++)
H[i] = -; // H[i]---第i行第一个为1的结点编号
}
void Link(int r,int c) // 行 列
{
// D[c] --- 第c列的下指针
S[Col[++size]=c]++; // 普通结点下标++ 第size个结点的列数是c 第c列的结点个数++
Row[size] = r; // 第size个结点的行数是r
D[size] = D[c]; // 第size个结点的下指针是:第0行第c列的下指针
U[size] = c; // 第size个结点的上指针是:第0行第c列 (只有输入行是递增时才可以这样)
U[D[c]] = size; // 第0行第c列的上指针是:size
D[c] = size; // size上面那个的下指针是:size (有点绕)
if(H[r] < ) H[r] = L[size] = R[size] = size; // 该行只有一个结点 左右指针自己指向自己
else
{
R[size] = R[H[r]]; // 成环
L[R[H[r]]] = size;
L[size] = H[r];
R[H[r]] = size;
}
}
void remove(int c) // 删除列c及其所在的行
{
L[R[c]] = L[c]; R[L[c]] = R[c]; // 左右两个结点连接,屏蔽掉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]]; // j所在的列的数目减少
}
}
void resume(int c) //恢复列c缩对应的行
{
for(int i = U[c];i != c;i = U[i])
for(int j = L[i];j != i;j = L[j])
++S[Col[U[D[j]]=D[U[j]]=j]];
L[R[c]] = R[L[c]] = c;
}
//d为递归深度
bool Dance(int d)
{
if(R[] == ) // R[0]==R[m] // 第0行已经没有结点
{
ansd = d;
return true;
}
int c = R[];
for(int i = R[];i != ;i = R[i]) // 往右走 ( 找出结点数最少的一列)
if(S[i] < S[c]) //第i列结点个数 < 第c列结点个数
c = i;
remove(c); // 移除列c所对应的行
for(int i = D[c];i != c;i = D[i]) // 找到最小的这一列往下走
{
ans[d] = Row[i];
for(int j = R[i]; j != i;j = R[j]) remove(Col[j]); // 移除该行所对应的列
if(Dance(d+))return true;//递归下一层
for(int j = L[i]; j != i;j = L[j])resume(Col[j]);//倒着恢复
}
resume(c);
return false;
}
}; DLX g;
int main()
{
//freopen("in.txt","r",stdin);
//freopen("out.txt","w",stdout);
int n,m;
while(scanf("%d%d",&n,&m) == )
{
g.init(n,m);
for(int i = ;i <= n;i++) // 行
{
int num,j;
scanf("%d",&num);
while(num--)
{
scanf("%d",&j); // 列
g.Link(i,j);
}
}
if(!g.Dance()) printf("NO\n");
else
{
printf("%d",g.ansd);
for(int i = ;i < g.ansd;i++)
printf(" %d",g.ans[i]);
printf("\n");
}
}
return ;
}

这个博客讲得非常细:

http://www.cnblogs.com/grenet/p/3145800.html

Dancing Link --- 模板题 HUST 1017 - Exact cover的更多相关文章

  1. HUST 1017 - Exact cover (Dancing Links 模板题)

    1017 - Exact cover 时间限制:15秒 内存限制:128兆 自定评测 5584 次提交 2975 次通过 题目描述 There is an N*M matrix with only 0 ...

  2. HUST 1017 Exact cover (Dancing links)

    1017 - Exact cover 时间限制:15秒 内存限制:128兆 自定评测 6110 次提交 3226 次通过 题目描述 There is an N*M matrix with only 0 ...

  3. [ACM] HUST 1017 Exact cover (Dancing Links,DLX模板题)

    DESCRIPTION There is an N*M matrix with only 0s and 1s, (1 <= N,M <= 1000). An exact cover is ...

  4. (简单) HUST 1017 Exact cover , DLX+精确覆盖。

    Description There is an N*M matrix with only 0s and 1s, (1 <= N,M <= 1000). An exact cover is ...

  5. HUST 1017 Exact cover(DLX精确覆盖)

    Description There is an N*M matrix with only 0s and 1s, (1 <= N,M <= 1000). An exact cover is ...

  6. HUST 1017 Exact cover dance links

    学习:请看 www.cnblogs.com/jh818012/p/3252154.html 模板题,上代码 #include<cstdio> #include<cstring> ...

  7. [HUST 1017] Exact cover

    Exact cover Time Limit: 15s Memory Limit: 128MB Special Judge Submissions: 6012 Solved: 3185 DESCRIP ...

  8. [DLX] hust 1017 Exact cover

    题意: 给你N个包,要拿到M个东西(编号1~M每一个仅仅能有一个) 然后每一个包里有k个东西,每一个东西都有编号. 思路: 舞蹈连模板题 代码: #include"stdio.h" ...

  9. hustoj 1017 - Exact cover dancing link

    1017 - Exact cover Time Limit: 15s Memory Limit: 128MB Special Judge Submissions: 5851 Solved: 3092 ...

随机推荐

  1. Hibernate不调用update却自动更新

    案例: TInfCustomer cus = (TInfCustomer) this.baseDao.getOne(helper); cus.setXXX cus .setXXX 不调用update也 ...

  2. database link

    create database link lims_qumas_supplyconnect to QPROCESSDEV identified by qprocessdevusing '(DESCRI ...

  3. struts2:上传多个文件时实现带进度条、进度详细信息的示范

    上一篇文章讲了上传单个文件与上传多个文件(属性驱动)的例子.本例是上传多个文件(属性驱动),并且显示进度条.进度详细信息的示范. 在文件上传选择界面,允许用户增加.删除选择的文件,且只能上传指定类型的 ...

  4. 实现 Dispose 方法

    实现 Dispose 方法 MSDN 类型的 Dispose 方法应释放它拥有的所有资源.它还应该通过调用其父类型的 Dispose 方法释放其基类型拥有的所有资源.该父类型的 Dispose 方法应 ...

  5. .NET Framework 高级开发

    .NET Framework 高级开发 MSDN 这部分帮助介绍与 .NET Framework 相关的高级编程主题. 本节内容 管理 介绍如何管理 Active Directory 中的对象,如何使 ...

  6. android 开发 - 网络图片加载库 Fresco 的使用。

    概述 Fresco 是 facebook 的开源类库,它支持更有效的加载网络图片以及资源图片.它自带三级缓存功能,让图片显示更高效. 介绍 Fresco 是一个强大的图片加载组件. Fresco 中设 ...

  7. [论文笔记] Methodologies for Data Quality Assessment and Improvement (ACM Comput.Surv, 2009) (2)

    本篇博文主要对DMQ(S3.7)的分类进行了研读. 1. 这个章节提出了一种DQM的分类法(如下图) 由上图可见,该分类法的分类标准是对assessment & improvement阶段的支 ...

  8. iOS8中使用CoreLocation定位[转]

    本文转自:http://blog.devzeng.com/blog/ios8-corelocation-framework.html iOS8以前使用CoreLocation定位 1.首先定义一个全局 ...

  9. 关于float /double、string类型的hash函数/hash表实现(转)

    #include <ext/hash_map> #include <math.h> #include <stdio.h> using namespace std; ...

  10. iOS 企业证书发布app 流程

    企业发布app的 过程比app store 发布的简单多了,没那么多的要求,哈 但是整个工程的要求还是一样,比如各种像素的icon啊 命名规范啊等等. 下面是具体的流程 1.修改你的 bundle i ...