题意:给你一个01矩阵,然后求是否存在选择一些行,使得每一列的1的个数都为1。

思路:貌似朴素的DFS也可以,加点剪枝就可以过。这里贴个DLX的模版。

推荐博客:http://www.cppblog.com/notonlysuccess/archive/2009/07/10/89701.html

这里讲的很详细。

#include <set>
#include <map>
#include <stack>
#include <cmath>
#include <queue>
#include <cstdio>
#include <string>
#include <vector>
#include <iomanip>
#include <cstring>
#include <iostream>
#include <algorithm>
#define Max 2505
#define FI first
#define SE second
#define ll long long
#define PI acos(-1.0)
#define inf 0x3fffffff
#define LL(x) ( x << 1 )
#define bug puts("here")
#define PII pair<int,int>
#define RR(x) ( x << 1 | 1 )
#define mp(a,b) make_pair(a,b)
#define mem(a,b) memset(a,b,sizeof(a))
#define REP(i,s,t) for( int i = ( s ) ; i <= ( t ) ; ++ i ) using namespace std; #define N 5555 ///DLX
int L[N] , R[N] , D[N] , U[N] ,S[N] , C[N] ,st[N] ;//S[] 表示这一列的点数。C[] 表示这个点位于那一列。
int n , m , num , head ; void insert(int col , int pos){//在这一列插入序号为pos的点
int now = col ;
while(D[now] != col) now = D[now] ;
D[now] = pos ;
D[pos] = col ;
U[pos] = now ;
U[col] = pos ;
} void init(){
head = 0 ;
R[head] = 1 ;L[head] = m ;
for (int i = 1 ; i <= m ; i ++ ){//每一行的头指针
if(i == 1)L[i] = head ;
else L[i] = i - 1 ;
if(i == m)R[i] = head ;
else R[i] = i + 1 ;
U[i] = i ;
D[i] = i ;
S[i] = 0 ;
C[i] = i ;
}
num = m ;//已经插入m个节点
int k ;
for (int i = 1 ; i <= n ; i ++ ){
mem(st ,0) ;
for (int j = 1 ; j <= m ; j ++ ){
scanf("%d",&k) ;
if(!k)continue ;
num ++ ;
insert(j , num) ;
if(st[0] == 0){//每行的第一个
L[num] = num ; R[num] = num ;
}else{
L[num] = st[st[0]] ;
R[num] = st[1] ;
R[st[st[0]]] = num ;
L[st[1]] = num ;
}
st[++st[0]] = num ;
C[num] = j ;
S[j] ++ ;
}
}
} void remove(const int &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[C[j]] ;
}
}
} void resume(const int &c){//恢复
for (int i = U[c] ; i != c ; i = U[i]){
for (int j = L[i] ; j != i ; j = L[j]){
++ S[C[j]] ;
U[D[j]] = j ;
D[U[j]] = j ;
}
}
L[R[c]] = c ;
R[L[c]] = c ;
} int dfs(const int &k){
if(R[head] == head)return 1 ;
int MX = inf ,c ;
for (int t = R[head] ; t != head ; t = R[t]){//找出点最少的一列
if(S[t] < MX){
MX = S[t] ;
c = t ;
}
}
remove(c) ;
for (int i = D[c] ; i != c ; i = D[i]){
for (int j = R[i] ; j != i ; j = R[j]){
remove(C[j]) ;
}
if(dfs(k + 1))return 1 ;
for (int j = L[i] ; j != i ; j = L[j]){
resume(C[j]) ;
}
}
resume(c) ;
return 0 ;
}
int main() {
while(cin >> n >> m){
init() ;
if(dfs(0))puts("Yes, I found it") ;
else puts("It is impossible") ;
}
return 0 ;
}

POJ 3740 DLX的更多相关文章

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

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

  2. [ACM] POJ 3740 Easy Finding (DLX模板题)

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

  3. Easy Finding POJ - 3740 (DLX)

    显然这是一道dfs简单题 或许匹配也能做 然而用了dancing links 显然这也是一道模板题 好的吧 调了一上午 终于弄好了模板 Easy Finding Time Limit: 1000MS ...

  4. 【POJ 3740】 Easy Finding

    [题目链接] http://poj.org/problem?id=3740 [算法] Dancing Links算法解精确覆盖问题 详见这篇文章 : https://www.cnblogs.com/g ...

  5. POJ 3740

    http://poj.org/problem?id=3740 这是一道搜索+回溯的题目,也是我第一次接触到回溯. 题意就是找一些行,这些行可以使每一列都只存在一个1. 深搜加回溯: memory:11 ...

  6. poj 3740 Easy Finding 精确匹配

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

  7. POJ 3740 Dancing Links

    Dancing Links学习:http://www.cnblogs.com/steady/archive/2011/03/15/1984791.html 以及图文学习:http://www.cnbl ...

  8. poj 3740 Easy Finding(Dancing Links)

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

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

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

随机推荐

  1. Bootstrap+Thinkphp3.2+Auth认证+jquery-validator后台

    Auth权限认证 本例采用auth权限认证,用户和用户组采用多对多关系处理,自动添加rule规则,带有jquery-validator插件,自动控制菜单显示或隐藏.   config.php中的配置 ...

  2. Spring 系列: Spring 框架简介(转载)

    Spring 系列: Spring 框架简介 http://www.ibm.com/developerworks/cn/java/wa-spring1/ Spring AOP 和 IOC 容器入门 在 ...

  3. Entity Framewor中的 Migration

    http://www.entityframeworktutorial.net/code-first/code-based-migration-in-code-first.aspx = Code bas ...

  4. web安全测试工具介绍---webscarab

    webscarab: 这主要是一款代理软件或许没有其它的工具能和OWASP的WebScarab如此丰富的功能相媲美了,如果非要列举一些有用的模块的话,那么他们包括HTTP代理,网络爬行.网络蜘蛛,会话 ...

  5. Mysql 利用multiline 实现多行匹配

    <pre name="code" class="html">input { file { type => "zj_mysql&quo ...

  6. Boost库学习之旅入门篇

    学习及使用Boost库已经有一段时间了,Boost为我的日常开发中带来了极大的方便,也使得我越来越依赖于boost库了.但boost功能太多,每次使用还是得翻看以前的 资料,所以为了以后可以更方便的使 ...

  7. ILSpy,DLL反编译工具,学习与了解原理的好帮手

    你是否一直苦于找到了好的dll却只知道怎么使用而不知道其原理. 你是否在使用一个dll的时候发现它在一些参数时报错了却没法解决. 你是否想成为一个优秀的.net开发,成为一个优秀的系统制造者. 那你需 ...

  8. sql server中将一个表中的部分数据插入到另一个表中

    可以通过存储过程完成,也可以通过在库名上右击“新建查询”执行.语句其实基本相同. 1. 存储过程: CREATE PROCEDURE pro1 as insert into tableB (field ...

  9. Apache Thrift入门(安装、测试与java程序编写)

    安装Apache Thrift ubuntu linux运行: #!/bin/bash #下载 wget http://mirrors.cnnic.cn/apache/thrift/0.9.1/thr ...

  10. Devexpress之barManager控件属性

    隐藏菜单栏左边的竖线和右边的箭头? 1.隐藏菜单栏上右边的箭头属性设置:OptionsBar=>>AllowQuickCustomization=False 2.隐藏菜单栏左边的竖线属性设 ...