题目链接:https://vjudge.net/problem/HUST-1017

1017 - Exact cover

时间限制:15秒 内存限制:128兆

自定评测 7673
次提交 3898 次通过
题目描述
There is an N*M matrix with only 0s and 1s, (1 <= N,M <= 1000). An exact cover is a selection of rows such that every column has a 1 in exactly one of the selected rows. Try to find out the selected rows.
输入
There are multiply test cases. First line: two integers N, M; The following N lines: Every line first comes an integer C(1 <= C <= 100), represents the number of 1s in this row, then comes C integers: the index of the columns whose value is 1 in this row.
输出
First output the number of rows in the selection, then output the index of the selected rows. If there are multiply selections, you should just output any of them. If there are no selection, just output "NO".
样例输入
6 7
3 1 4 7
2 1 4
3 4 5 7
3 3 5 6
4 2 3 6 7
2 2 7
样例输出
3 2 4 6
提示
来源
dupeng

代码如下:

#include <iostream>
#include <cstdio>
#include <cstring>
#include <cmath>
#include <algorithm>
#include <vector>
#include <queue>
#include <stack>
#include <map>
#include <string>
#include <set>
#define ms(a,b) memset((a),(b),sizeof((a)))
using namespace std;
typedef long long LL;
const int MAXN = 1e3+10;
const int MAXM = 1e3+10;
const int maxnode = 1e6+10; int n, m;
struct DLX //矩阵的行和列是从1开始的
{
int n, m, size; //size为结点数
int U[maxnode], D[maxnode], L[maxnode], R[maxnode], Row[maxnode], Col[maxnode];
int H[MAXN], S[MAXM]; //H为每一行的头结点,但不参与循环。S为每一列的结点个数
int ansd, ans[MAXN]; void init(int _n, int _m) //m为列
{
n = _n;
m = _m;
for(int i = 0; i<=m; i++) //初始化列的头结点
{
S[i] = 0;
U[i] = D[i] = i;
L[i] = i-1;
R[i] = i+1;
}
R[m] = 0; L[0] = m;
size = m;
for(int i = 1; i<=n; i++) H[i] = -1; //初始化行的头结点
} void Link(int r, int c)
{
size++; //类似于前向星
Col[size] = c;
Row[size] = r;
S[Col[size]]++;
D[size] = D[c];
U[D[c]] = size;
U[size] = c;
D[c] = size;
if(H[r]==-1) H[r] = L[size] = R[size] = size; //当前行为空
else //当前行不为空: 头插法,无所谓顺序,因为Row、Col已经记录了位置
{
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]]--;
}
} void resume(int c)
{
L[R[c]] = R[L[c]] = c;
for(int i = U[c]; i!=c; i = U[i])
for(int j = L[i]; j!=i; j = L[j])
{
U[D[j]] = D[U[j]] = j;
S[Col[j]]++;
}
} bool Dance(int d)
{
if(R[0]==0)
{
printf("%d ", d);
for(int i = 0; i<d; i++)
printf("%d ", ans[i]);
printf("\n");
return true;
} int c = R[0];
for(int i = R[0]; i!=0; i = R[i]) //挑结点数最少的那一列,否则会超时,那为什么呢?
if(S[i]<S[c])
c = i; remove(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+1)) return true;
for(int j = L[i]; j!=i; j = L[j]) resume(Col[j]);
}
resume(c);
return false;
}
}; DLX dlx;
int main()
{
while(scanf("%d%d", &n, &m)!=EOF)
{
dlx.init(n,m); //初始化矩阵, n*m为矩阵的大小
for(int i = 1; i<=n; i++)
{
int num, j;
scanf("%d",&num);
while(num--)
{
scanf("%d", &j);
dlx.Link(i, j); //在矩阵中的第i行, 第j列加入一个“1”
}
}
if(!dlx.Dance(0))
puts("NO");
}
return 0;
}

HUST1017 Exact cover —— Dancing Links 精确覆盖 模板题的更多相关文章

  1. hust 1017 dancing links 精确覆盖模板题

    最基础的dancing links的精确覆盖题目 #include <iostream> #include <cstring> #include <cstdio> ...

  2. [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 ...

  3. 【转】Dancing Links精确覆盖问题

    原文链接:http://sqybi.com/works/dlxcn/ (只转载过来一部分,全文请看原文,感觉讲得很好~)正文    精确覆盖问题    解决精确覆盖问题    舞蹈步骤    效率分析 ...

  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. hihoCoder #1321 : 搜索五•数独 (Dancing Links ,精确覆盖)

    hiho一下第102周的题目. 原题地址:http://hihocoder.com/problemset/problem/1321 题意:输入一个9*9数独矩阵,0表示没填的空位,输出这个数独的答案. ...

  6. HUST 1017 Exact cover (Dancing links)

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

  7. ZOJ 3209 Treasure Map (Dancing Links 精确覆盖 )

    题意 :  给你一个大小为 n * m 的矩形 , 坐标是( 0 , 0 ) ~ ( n , m )  .然后给你 p 个小矩形 . 坐标是( x1 , y1 ) ~ ( x2 , y2 ) , 你选 ...

  8. HDU 3111 Sudoku ( Dancing Links 精确覆盖模型 )

    推荐两篇学DLX的博文: http://bbs.9ria.com/thread-130295-1-1.html(这篇对DLX的工作过程演示的很详细) http://yzmduncan.iteye.co ...

  9. POJ3074 Sudoku —— Dancing Links 精确覆盖

    题目链接:http://poj.org/problem?id=3074 Sudoku Time Limit: 1000MS   Memory Limit: 65536K Total Submissio ...

随机推荐

  1. 理解 virbr0

    virbr0 是 KVM 默认创建的一个 Bridge,其作用是为连接其上的虚机网卡提供 NAT 访问外网的功能. virbr0 默认分配了一个IP 192.168.122.1,并为连接其上的其他虚拟 ...

  2. golang并发编程goroutine+channel(一)

    go语言的设计初衷除了在不影响程序性能的情况下减少复杂度,另一个目的是在当今互联网大量运算下,如何让程序的并发性能和代码可读性达到极致.go语言的并发关键词 "go" go dos ...

  3. Codeforces 552E Vanya and Brackets(枚举 + 表达式计算)

    题目链接 Vanya and Brackets 题目大意是给出一个只由1-9的数.乘号和加号组成的表达式,若要在这个表达式中加上一对括号,求加上括号的表达式的最大值. 我们发现,左括号的位置肯定是最左 ...

  4. Windows下配置scrapy需要MVC的14.0版本(转载)

    转载于--http://blog.csdn.net/MrWilliamVs/article/details/77130965 杨煜冬煜杨的博客,他的博客比较杂,Java.Python都有--http: ...

  5. Centos7 下的防火墙端口配置

    如果外部不能访问,需要查看防火墙以及服务器的端口安全设置. 防火墙的操作 查看所有打开的端口: firewall-cmd --zone=public --list-ports 添加 firewall- ...

  6. 还在为不停build 烦恼么?看这里~~

    如果你是一名开发者,还在为偶尔改一个坐标或者颜色值 就要重新build 好久,然后如果层次深 还要一步步进去看效果么?下面 为大家介绍一个很好的开源库  DYCI  他的github地址,首先下载到本 ...

  7. Action Bar详解(二)

    在Android3.0之后,Google对UI导航设计上进行了一系列的改革,其中有一个非常好用的新功能就是引入的ActionBar,他用于取代3.0之前的标题栏,并提供更为丰富的导航效果. 一.添加A ...

  8. JavaScript 层

    代码Code highlighting produced by Actipro CodeHighlighter (freeware)http://www.CodeHighlighter.com/--& ...

  9. BUPT复试专题—中序遍历序列(2013)

    题目描述 给出一个序列,判断该序列是不是某二叉搜索树的中序遍历序列,如果是输出"Yes",否则输出"No".一颗带权二叉树是一颗二叉搜索树(二叉排序树),当且仅 ...

  10. time machine不备份指定文件夹

    osx中常常会使用timemachine来备份一些文件,timemachine能够使某个文件夹恢复到之前某个时刻的状态,很的方便.但是备份须要空间,特别是有些我们并不想备份一些无关紧要的文件,比方电影 ...