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. Linux文件名小写的好处(转)

    说明:来自老阮的<为什么文件名要小写>的文章,其实我觉得应该说是<Linux文件名为什么要小写>会更合适些. 一.可移植性 Linux 系统是大小写敏感的,而 Windows ...

  2. FIREDAC记录SQL日志

    FIREDAC记录SQL日志 跟踪SQL日志可以方便开发的时候的程序调试.SQL日志记录会耗费服务费资源,正式部署中间件的时候,建议关闭SQL日志记录. FIREDAC通过使用TFDMoniFlatF ...

  3. 基于pydash临控linux服务器

    pydash项目地址:https://github.com/k3oni/pydash 一.安装过程 1.安装pip dnf install git python-pip -ypip install v ...

  4. asp.net购物车,订单以及模拟支付宝支付(三)---提交订单

    在设计完订单表之后,就要整理一下订单处理的流程了 首先,用户在购物车界面点击结算的时候,跳到一个结算确认页面(这时候只是确认,让用户填写收货地址等,没有真正的下订单),显示用户的地址等信息和要买的物品 ...

  5. 【重点突破】—— Easy Mock的使用及Mock.js规范

    前言:在线使用Easy Mock可视化工具,可以提供快速生成“模拟数据”的持久化服务: Mock.js是一个JS插件,指定了一套规范,而Easy Mock工具就遵循这些规范.  一.Easy Mock ...

  6. 用MyEclipse2016 CI版创建一个SpringBoot程序

    之前先要在Eclipse里安装STS,步骤如下: 1.点击菜单Help->Install from Catalog 2.在弹出的对话框中点击Popular选项卡,在STS旁边点Install按钮 ...

  7. Java程序猿的JavaScript学习笔记(12——jQuery-扩展选择器)

    计划按例如以下顺序完毕这篇笔记: Java程序猿的JavaScript学习笔记(1--理念) Java程序猿的JavaScript学习笔记(2--属性复制和继承) Java程序猿的JavaScript ...

  8. Python学习笔记(二)网络编程的简单示例

    Python中的网络编程比C语言中要简洁很多,毕竟封装了大量的细节. 所以这里不再介绍网络编程的基本知识.而且我认为,从Python学习网络编程不是一个明智的选择.   简单的TCP连接 服务器代码如 ...

  9. PHP结巴程序实现

    <?php $str="我...我要要要...学学学..编编程"; $str=preg_replace('/\./','',$str);//我我要要要学学学编编程 $str= ...

  10. angularjs与server交互

    真正的应用须要和真实的server进行交互,移动应用和新兴的Chrome桌面应用可能是个例外,可是对于此外的全部应用来说,不管你是想把数据持久化到云端.还是须要与其它用户进行实时交互.都须要让应用与s ...