DESCRIPTION
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.
INPUT
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.
OUTPUT
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".
SAMPLE INPUT
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
SAMPLE OUTPUT
3 2 4 6
HINT
SOURCE
dupeng

题目地址:http://acm.hust.edu.cn/problem/show/1017

DLX 学习资料:

http://blog.sina.com.cn/s/blog_7d44748b01013fsf.html      图文并茂通过地址解释双向链表 (基础!)

http://wenku.baidu.com/view/d8f13dc45fbfc77da269b126.html  Knuth论文中文版

http://wenku.baidu.com/view/4ab7bd00a6c30c2259019eae.html  Dancing Links在搜索中的应用 momodi论文

http://www.cnblogs.com/grenet/p/3145800.html    强烈推荐!作者把全然覆盖问题搜索过程完整得用文字和图片写了下来,非常好懂。

參考:http://www.cnblogs.com/kuangbin/p/3752854.html  kuangbin模板

Dlx真的非常奇异,先是看资料,然后又研究模板,看完上面的链接资料对学习DLX非常有帮助。

最经典的就是全然覆盖问题。

本题就是给定一个由0,1元素组成的矩阵,问取出哪几行,能够使这几行构成的新矩阵,每列仅仅有一个1.

代码:

#include <iostream>
#include <stdio.h>
using namespace std;
const int maxnode=100010;
const int maxm=1010;
const int maxn=1010; struct DLX
{
int n,m,size;
int U[maxnode],D[maxnode],R[maxnode],L[maxnode],Row[maxnode],Col[maxnode];
int H[maxn];//行头节点
int S[maxm];//每列有多少个节点
int ansd,ans[maxn];//假设有答案,则选了ansd行,详细是哪几行放在ans[ ]数组里面,ans[0~ansd-1]; void init(int _n,int _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;//编号,每列都有一个头节点,编号1-m
for(int i=1;i<=n;i++)
H[i]=-1;//每一行的头节点
} void link(int r,int c)//第r行,第c列
{
++S[Col[++size]=c];//第size个节点所在的列为c,当前列的节点数++
Row[size]=r;//第size个节点行位置为r
D[size]=D[c];//以下这四句头插法(图是倒着的?)
U[D[c]]=size;
U[size]=c;
D[c]=size;
if(H[r]<0)
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,以及c上下节点所在的行,每次调用这个函数,都是从列头节点開始向下删除,这里c也能够理解为第c列
{ //由于第c列的列头节点编号为c
L[R[c]]=L[c];
R[L[c]]=R[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)//恢复节点c,以及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]]; //打这一行太纠结了 T T
L[R[c]]=R[L[c]]=c;
} bool dance(int d)//递归深度
{
if(R[0]==0)
{
ansd=d;
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);//找到节点数最少的列,当前元素不是原图上0,1的节点,而是列头节点
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 x;
int n,m; int main()
{
while(scanf("%d%d",&n,&m)!=EOF)
{
x.init(n,m);
for(int i=1;i<=n;i++)
{
int cnt,j;
scanf("%d",&cnt);
while(cnt--)
{
scanf("%d",&j);
x.link(i,j);
}
}
if(!x.dance(0))
printf("NO\n");
else
{
printf("%d",x.ansd);
for(int i=0;i<x.ansd;i++)
printf(" %d",x.ans[i]);
printf("\n");
}
}
return 0;
}

[ACM] HUST 1017 Exact cover (Dancing Links,DLX模板题)的更多相关文章

  1. HUST 1017 Exact cover (Dancing links)

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

  2. HUST 1017 Exact cover dance links

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

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

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

  4. Dancing Link --- 模板题 HUST 1017 - Exact cover

    1017 - Exact cover Problem's Link:   http://acm.hust.edu.cn/problem/show/1017 Mean: 给定一个由0-1组成的矩阵,是否 ...

  5. hustoj 1017 - Exact cover dancing link

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

  6. HUST1017 Exact cover —— Dancing Links 精确覆盖 模板题

    题目链接:https://vjudge.net/problem/HUST-1017 1017 - Exact cover 时间限制:15秒 内存限制:128兆 自定评测 7673 次提交 3898 次 ...

  7. (简单) 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 ...

  8. 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 ...

  9. [DLX] hust 1017 Exact cover

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

随机推荐

  1. poj3254(状压dp)

    题目连接:http://poj.org/problem?id=3254 题意:一个矩阵里有很多格子,每个格子有两种状态,可以放牧和不可以放牧,可以放牧用1表示,否则用0表示,在这块牧场放牛,要求两个相 ...

  2. hdu4487(概率dp)

    题目连接:http://acm.hdu.edu.cn/showproblem.php?pid=4487 题意:开始位置在0,每一步可以向右向左或者不动,问走了n步后,路径中能到达最右的期望. 分析:d ...

  3. C++ Primer中文版(第5版)

    <C++ Primer中文版(第5版)> 基本信息 作者: (美)Stanley B. Lippman(斯坦利 李普曼)    Josee Lajoie(约瑟 拉乔伊)    Barbar ...

  4. 华为C8816电信版ROOT过程

    华为C8816电信版ROOT方法, 网上的方法都不太靠谱.. 昨天弄了好久, 最终搞定.. 整理了一下.. 实用到的就方便多了. <方法不再啰嗦, 都有说明> 1. 获取手机解锁passw ...

  5. 命令含执行JAVA程序

    1.当类没有包名时 javac Test.java java Test   2.当有包名情况下 package com.me.Test; javac -d . Test.java java com.m ...

  6. class 添加样式,删,开关 【选择】addClass,removeClass,toggleClass

    <1> <html xmlns="http://www.w3.org/1999/xhtml"> <head> <title>< ...

  7. PSU 离11.2.0.3.0 -&gt; 11.2.0.3.11 如果解决冲突的整个

    Oracle rdbms 扑灭psu离11.2.0.3.0升级到11.2.0.3.11 参考patch :18522512 停止应用,停止听音乐并DB,将db的oracle_home在下面OPatch ...

  8. NET通用平台

    NET通用平台.通用权限.易扩展.多语言.多平台架构框架 先拿出我半前年前平台的设计初稿,经过半年的努力我已经完成了该设计稿的所有功能.并且理念已经远远超出该设计稿. 下面是一些博友对我贴子的评价: ...

  9. SSH是什么?Linux如何修改SSH端口号?

    通过SSH连接可以远程管理Linux等设备,默认linuxssh端口是22端口,如何修改SSH默认端口,如何增加SSH端口呢?,下面小编给大家演示一下   工具/原料 Xshell   putty 等 ...

  10. Unity多玩家网络游戏开发教程1章Unity带有网络功能

    Unity网络多玩家游戏开发教程第1章Unity自带网络功能 Unity拥有大量的第三方插件.专门提供了对网络功能的支持. 可是.大部分开发人员第一次接触到的还是Unity自带的网络功能.也就是大家常 ...