[ACM] POJ 3740 Easy Finding (DLX模板题)
Time Limit: 1000MS | Memory Limit: 65536K | |
Total Submissions: 16178 | Accepted: 4343 |
Description
1.
Input
M, N (M ≤ 16, N ≤ 300). The next M lines every line contains
N integers separated by space.
Output
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模板题)的更多相关文章
- [ACM] POJ 3740 Easy Finding (DFS)
Time Limit: 1000MS Memory Limit: 65536K Total Submissions: 16202 Accepted: 4349 Description Give ...
- poj 3740 Easy Finding 二进制压缩枚举dfs 与 DLX模板详细解析
题目链接:http://poj.org/problem?id=3740 题意: 是否从0,1矩阵中选出若干行,使得新的矩阵每一列有且仅有一个1? 原矩阵N*M $ 1<= N <= 16 ...
- poj 3740 Easy Finding(Dancing Links)
Easy Finding Time Limit: 1000MS Memory Limit: 65536K Total Submissions: 15668 Accepted: 4163 Des ...
- poj 3740 Easy Finding 精确匹配
题目链接 dlx的第一题, 真是坎坷..... #include <iostream> #include <vector> #include <cstdio> #i ...
- POJ 3740 Easy Finding
#include<cstdio> #include<cstring> #include<cmath> #include<algorithm> using ...
- POJ 3068 运送危险化学品 最小费用流 模板题
"Shortest" pair of paths Time Limit: 1000MS Memory Limit: 65536K Total Submissions: 1215 ...
- POJ 1287 Networking【kruskal模板题】
传送门:http://poj.org/problem?id=1287 题意:给出n个点 m条边 ,求最小生成树的权 思路:最小生树的模板题,直接跑一遍kruskal即可 代码: #include< ...
- POJ 1502 MPI Maelstrom(模板题——Floyd算法)
题目: BIT has recently taken delivery of their new supercomputer, a 32 processor Apollo Odyssey distri ...
- POJ 1470 Closest Common Ancestors (模板题)(Tarjan离线)【LCA】
<题目链接> 题目大意:给你一棵树,然后进行q次询问,然后要你统计这q次询问中指定的两个节点最近公共祖先出现的次数. 解题分析:LCA模板题,下面用的是离线Tarjan来解决.并且为了代码 ...
随机推荐
- CocoaPods安装使用及配置私有库及注意点
如何安装? 1.安装ruby环境,添加淘宝ruby镜像 $ gem sources --remove https://rubygems.org///等有反应之后再敲入以下命令$ gem sources ...
- 初识交替最小二乘ALS
ALS是alternating least squares的缩写 , 意为交替最小二乘法:而ALS-WR是alternating-least-squares with weighted-λ -regu ...
- KVM Network Bridging
from http://hzqtc.github.io/2012/02/kvm-network-bridging.html http://wiki.ubuntu.org.cn/Kvm_%E7%BD%9 ...
- 如何使用Delphi编写Modbus RTU CRC16的校验码
在工业控制中,Modbus RTU CRC16的校验码用的比较广泛,包括本人富士产品中,PC与伺服电机以及PC与VP系列的变频器的Modbus RTU通讯中都使用到了CRC16. 而对CRC1 ...
- BFS求最短路
假设有一个n行m列的迷宫,每个单位要么是空地(用1表示)要么是障碍物(用0表示).如和找到从起点到终点的最短路径?利用BFS搜索,逐步计算出每个节点到起点的最短距离,以及最短路径每个节点的前一个节点. ...
- 改变PS1变量的颜色
2016.1.11今天学了改变PS1的颜色,怎么增加PS1变量找到文件(.bash_profile),或者bashrc export PS1="\[\e[32;1m\]Test $PWD&g ...
- ES6中的迭代器(Iterator)和生成器(Generator)(一)
用循环语句迭代数据时,必须要初始化一个变量来记录每一次迭代在数据集合中的位置,而在许多编程语言中,已经开始通过程序化的方式用迭代器对象返回迭代过程中集合的每一个元素 迭代器的使用可以极大地简化数据操作 ...
- 浅谈C#委托和事件(转载)
委托给了C#操作函数的灵活性,我们可使用委托像操作变量一样来操作函数,其实这个功能并不是C#的首创,早在C++时代就有函数指针这一说法,而在我看来委托就是C#的函数指针,首先先简要的介绍一下委托的基本 ...
- Angularjs中的拦截器 (卧槽,好牛逼)
$httpAngularJS 的 $http 服务允许我们通过发送 HTTP 请求方式与后台进行通信.在某些情况下,我们希望可以俘获所有的请求,并且在将其发送到服务端之前进行操作.还有一些情况是,我们 ...
- 2017.7.1 nginx反向代理服务器域名解析配置(已验证可使用)
下载地址:http://learning.happymmall.com/ 前提:ftpserver已经开启,并且设置为: 1.获得安装文件 2.修改配置文件 2.1 修改conf/nginx.conf ...