Easy Finding
Time Limit: 1000MS   Memory Limit: 65536K
Total Submissions: 16178   Accepted: 4343

Description

Given a M×N matrix A. Aij ∈ {0, 1} (0 ≤ i < M, 0 ≤ j < N), could you find some rows that let every cloumn contains and only contains one
1.

Input

There are multiple cases ended by EOF. Test case up to 500.The first line of input is
M, N (M ≤ 16, N ≤ 300). The next M lines every line contains
N integers separated by space.

Output

For each test case, if you could find it output "Yes, I found it", otherwise output "It is impossible" per line.

Sample Input

3 3
0 1 0
0 0 1
1 0 0
4 4
0 0 0 1
1 0 0 0
1 1 0 1
0 1 0 0

Sample Output

Yes, I found it
It is impossible

Source

解题思路:

题意为由01组成的矩阵,问能不能挑出几行使组成的新矩阵每列仅仅有一个1.

套用Dlx模板,只是G++ 超时。C++勉强能过。

代码:

#include <iostream>
#include <stdio.h>
using namespace std;
const int maxnode=5000;
const int maxm=310;
const int maxn=18; 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);
int num;
for(int i=1;i<=n;i++)
{
for(int j=1;j<=m;j++)
{
cin>>num;
if(num)
x.link(i,j);
}
}
if(!x.dance(0))
printf("It is impossible\n");
else
printf("Yes, I found it\n");
}
return 0;
}

[ACM] POJ 3740 Easy Finding (DLX模板题)的更多相关文章

  1. [ACM] POJ 3740 Easy Finding (DFS)

    Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 16202   Accepted: 4349 Description Give ...

  2. poj 3740 Easy Finding 二进制压缩枚举dfs 与 DLX模板详细解析

    题目链接:http://poj.org/problem?id=3740 题意: 是否从0,1矩阵中选出若干行,使得新的矩阵每一列有且仅有一个1? 原矩阵N*M $ 1<= N <= 16 ...

  3. poj 3740 Easy Finding(Dancing Links)

    Easy Finding Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 15668   Accepted: 4163 Des ...

  4. poj 3740 Easy Finding 精确匹配

    题目链接 dlx的第一题, 真是坎坷..... #include <iostream> #include <vector> #include <cstdio> #i ...

  5. POJ 3740 Easy Finding

    #include<cstdio> #include<cstring> #include<cmath> #include<algorithm> using ...

  6. POJ 3068 运送危险化学品 最小费用流 模板题

    "Shortest" pair of paths Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 1215 ...

  7. POJ 1287 Networking【kruskal模板题】

    传送门:http://poj.org/problem?id=1287 题意:给出n个点 m条边 ,求最小生成树的权 思路:最小生树的模板题,直接跑一遍kruskal即可 代码: #include< ...

  8. POJ 1502 MPI Maelstrom(模板题——Floyd算法)

    题目: BIT has recently taken delivery of their new supercomputer, a 32 processor Apollo Odyssey distri ...

  9. POJ 1470 Closest Common Ancestors (模板题)(Tarjan离线)【LCA】

    <题目链接> 题目大意:给你一棵树,然后进行q次询问,然后要你统计这q次询问中指定的两个节点最近公共祖先出现的次数. 解题分析:LCA模板题,下面用的是离线Tarjan来解决.并且为了代码 ...

随机推荐

  1. 关于asp.net mvc中 weiui gallery中IOS 下不显示预览图片问题的解决方式

    IOS 下面不显示预览. 结果去掉了红框中的缓存部分 就可以显示了 备忘,也帮助一下需要的朋友 @*<meta http-equiv="pragma" content=&qu ...

  2. sqlserver 出现sql被锁时,查看加锁和被锁的sql

    原文:sqlserver 出现sql被锁时,查看加锁和被锁的sql DECLARE @spid INT DECLARE @blk INT DECLARE @count INT DECLARE @ind ...

  3. mailkit----163邮箱登录拉取邮件的坑

    在使用mailkit的ImapClient拉取邮件的时候,如果我们使用的是网易的邮箱(如:163.126等),如果你没有按照网易的设置去打开IMAP协议,那么将无法登录邮箱,并且发送一封使用不安全的客 ...

  4. java的几个概念AOP、IOC、DI、DIP、工厂模式、IOC容器

    1.AOP:面向切面编程 把一些公共类,比如日志类.安全类.数据库连接类.系统统一的认证.权限管理类.资源池(如数据库连接池的管理).性能监控等做成一个公共类,当其他类需要时,进行注入(调用).这样这 ...

  5. Linux Shell常用技巧

    转载自http://www.cnblogs.com/stephen-liu74/ 一.    特殊文件: /dev/null和/dev/tty Linux系统提供了两个对Shell编程非常有用的特殊文 ...

  6. Nginx反向代理、负载均衡及日志

    Nginx反向代理.负载均衡及日志 1.原理图   2.正向代理与反向代理 (1)代理服务器 代理服务器,客户机在发送请求时,不会直接发送给目的主机,而是先发送给代理服务器,代理服务接受客户机请求之后 ...

  7. SQL语句练习手册--第四篇

    一.变量那点事儿 1.1 局部变量 (1)声明局部变量 DECLARE @变量名 数据类型 ) DECLARE @id int (2)为变量赋值 SET @变量名 =值 --set用于普通的赋值 SE ...

  8. LeetCode题目:Permutations

    题目:Given a collection of distinct numbers, return all possible permutations. 大意:全排列给定数组,其中给定数组中没有相同的 ...

  9. STL学习笔记(算法概述)

    算法头文件 要运用C++标准程序库的算法,首先必须包含头文件<algorithm> 使用STL算法时,经常需要用到仿函数以及函数配接器.它们定义域<functional>头文件 ...

  10. 【VBA】VBA编写的,将一列中相同的内容的行提取出来单独生成文件

    数据如上图所示,点击RUN后的运行结果如下: 得到该文件夹,文件夹内容如上图. 代码如下: Private Sub Command_OLIVER() Dim arr arr = Range(" ...