POJ2688状态压缩(可以+DFS剪枝)
题意:
给你一个n*m的格子,然后给你一个起点,让你遍历所有的垃圾,就是终点不唯一,问你最小路径是多少?
思路:
水题,方法比较多,最省事的就是直接就一个BFS状态压缩暴搜就行了,时间复杂度20*20*1024的,完全可以接受,但是被坑了,一开始怎么交都TLE,后来又写了一个BFS+DFS优化,就是跑之前先遍历一遍图,看看是不是所有的垃圾点都能遍历到,这样还是超时,无奈看了下讨论,有人说用G++交就行了,我用G++交了结果两个方法都AC了,哎!下面是两个方法的代码,比较简单,最近就是无聊,上POJ来刷刷水题,还有这个题目,可以用DP去做,还有就是可以直接求出任意两个垃圾的最短距离,然后在枚举处理垃圾顺序,枚举可以用STL的全排列,也可以搜索,这样的时间复杂度大约是N!吧,跟直接暴搜没啥区别,想试的可以敲敲试试吧。
直接BFS状态压缩暴力625
#include<queue>
#include<stdio.h>
#include<string.h>
using namespace std;
typedef struct
{
int x ,y ,k ,t;
}NODE;
NODE xin ,tou;
int map[22][22] ,n ,m ,w;
int mark[22][22][1025];
int dir[4][2] = {0 ,1 ,0 ,-1 ,1 ,0 ,-1 ,0};
bool ok(int x ,int y ,int k)
{
return x >= 1 && x <= n && y >= 1 && y <= m && map[x][y] && !mark[x][y][k];
}
int BFS(int x ,int y)
{
queue<NODE>q;
xin.x = x ,xin.y = y;
xin.t = 0 ,xin.k = 0;
memset(mark ,0 ,sizeof(mark));
mark[xin.x][xin.y][xin.k] = 1;
q.push(xin);
while(!q.empty())
{
tou = q.front();
q.pop();
for(int i = 0 ;i < 4 ;i ++)
{
xin.x = tou.x + dir[i][0];
xin.y = tou.y + dir[i][1];
xin.t = tou.t + 1;
if(map[xin.x][xin.y] && map[xin.x][xin.y] != -1)
xin.k = tou.k | (1 << (map[xin.x][xin.y] - 1));
else xin.k = tou.k;
if(ok(xin.x ,xin.y ,xin.k))
{
mark[xin.x][xin.y][xin.k] = 1;
q.push(xin);
if(xin.k == (1 << w) - 1) return xin.t;
}
}
}
return -1;
}
int main ()
{
char str[22];
int x ,y;
while(~scanf("%d %d" ,&m ,&n) && n+m)
{
w = 0;
for(int i = 1 ;i <= n ;i ++)
{
scanf("%s" ,str);
for(int j = 1 ;j <= m ;j ++)
{
if(str[j-1] == '.') map[i][j] = -1;
else if(str[j-1] == '*') map[i][j] = ++w;
else if(str[j-1] == 'x') map[i][j] = 0;
else x = i ,y = j ,map[i][j] = -1;
}
}
w ? printf("%d\n" ,BFS(x ,y)):printf("0\n");
}
return 0;
}
BFS+DFS剪枝594
#include<queue>
#include<stdio.h>
#include<string.h>
using namespace std;
typedef struct
{
int x ,y ,k ,t;
}NODE;
NODE xin ,tou;
int col[22][22] ,cmk[22][22];
int map[22][22] ,n ,m ,w;
int mark[22][22][1025];
int dir[4][2] = {0 ,1 ,0 ,-1 ,1 ,0 ,-1 ,0};
bool ok(int x ,int y ,int k)
{
return x >= 1 && x <= n && y >= 1 && y <= m && map[x][y] && !mark[x][y][k];
}
int BFS(int x ,int y)
{
queue<NODE>q;
xin.x = x ,xin.y = y;
xin.t = 0 ,xin.k = 0;
memset(mark ,0 ,sizeof(mark));
mark[xin.x][xin.y][xin.k] = 1;
q.push(xin);
while(!q.empty())
{
tou = q.front();
q.pop();
for(int i = 0 ;i < 4 ;i ++)
{
xin.x = tou.x + dir[i][0];
xin.y = tou.y + dir[i][1];
xin.t = tou.t + 1;
if(map[xin.x][xin.y] && map[xin.x][xin.y] != -1)
xin.k = tou.k | (1 << (map[xin.x][xin.y] - 1));
else xin.k = tou.k;
if(ok(xin.x ,xin.y ,xin.k))
{
mark[xin.x][xin.y][xin.k] = 1;
q.push(xin);
if(xin.k == (1 << w) - 1) return xin.t;
}
}
}
return -1;
}
void DFS(int x ,int y)
{
for(int i = 0 ;i < 4 ;i ++)
{
int xx = x + dir[i][0];
int yy = y + dir[i][1];
if(xx >= 1 && xx <= n && yy >= 1 && yy <= m && !cmk[xx][yy] && map[xx][yy])
{
cmk[xx][yy] = 1;
DFS(xx ,yy);
}
}
}
int main ()
{
char str[22];
int x ,y;
while(~scanf("%d %d" ,&m ,&n) && n+m)
{
w = 0;
for(int i = 1 ;i <= n ;i ++)
{
scanf("%s" ,str);
for(int j = 1 ;j <= m ;j ++)
{
if(str[j-1] == '.') map[i][j] = -1;
else if(str[j-1] == '*') map[i][j] = ++w;
else if(str[j-1] == 'x') map[i][j] = 0;
else x = i ,y = j ,map[i][j] = -1;
}
}
memset(cmk ,0 ,sizeof(cmk));
DFS(x ,y);
int mk = 0;
for(int i = 1 ;i <= n && !mk;i ++)
for(int j = 1 ;j <= m && !mk;j ++)
if(map[i][j] != -1 && map[i][j] && !cmk[i][j])
mk = 1;
if(mk)
{
printf("-1\n");
continue;
}
w ? printf("%d\n" ,BFS(x ,y)):printf("0\n");
}
return 0;
}
POJ2688状态压缩(可以+DFS剪枝)的更多相关文章
- poj 1753 Flip Game(bfs状态压缩 或 dfs枚举)
Description Flip game squares. One side of each piece is white and the other one is black and each p ...
- uva10160(dfs+状态压缩)
题意:给出n个点,以及m条边,这些边代表着这些点相连,修一个电力站,若在某一点修一个站,那么与这个点相连的点都可以通电,问所有的点都通电的话至少要修多少个电力站........ 思路:最多给出的是35 ...
- Sudoku (剪枝+状态压缩+预处理)
[题目描述] In the game of Sudoku, you are given a large 9 × 9 grid divided into smaller 3 × 3 subgrids. ...
- codeforces B - Preparing Olympiad(dfs或者状态压缩枚举)
B. Preparing Olympiad You have n problems. You have estimated the difficulty of the i-th one as inte ...
- 最大联通子数组之和(dfs,记忆化搜索,状态压缩)
最大联通子数组,这次的题目,我采用的方法为dfs搜索,按照已经取到的数v[][],来进行搜索过程的状态转移,每次对v[][]中标记为1的所有元素依次取其相邻的未被标记为1的元素,将其标记为1,然而,这 ...
- UVA 1508 - Equipment 状态压缩 枚举子集 dfs
UVA 1508 - Equipment 状态压缩 枚举子集 dfs ACM 题目地址:option=com_onlinejudge&Itemid=8&category=457& ...
- hihocoder 1334 - Word Construction - [hiho一下第170周][状态压缩+DFS]
题目链接:https://hihocoder.com/problemset/problem/1334 时间限制:10000ms 单点时限:1000ms 内存限制:256MB 描述 Given N wo ...
- Preparing Olympiad---cf550B(DFS或者状态压缩模板)
比赛链接:http://codeforces.com/problemset/problem/550/B 给你n个数,选出来只是2个然后求他们的和在L和R的区间内,并且选出来的数中最大值和最小值的差不得 ...
- poj 3311 floyd+dfs或状态压缩dp 两种方法
Hie with the Pie Time Limit: 2000MS Memory Limit: 65536K Total Submissions: 6436 Accepted: 3470 ...
随机推荐
- SpringMVC-01 什么是SpringMVC
SpringMVC-01 什么是SpringMVC 回顾MVC 1.什么是MVC MVC是模型(Model).视图(View).控制器(Controller)的简写,是一种软件设计规范. 是将业务逻辑 ...
- 数据库事务 ACID属性、数据库并发问题和四种隔离级别
数据库事务 ACID属性.数据库并发问题和四种隔离级别 数据库事务 数据库事务是一组逻辑操作单元,使数据从一种状态变换到另一种状态 一组逻辑操作单元:一个或多个DML操作 事务处理原则 保证所有事务都 ...
- 2020年12月-第02阶段-前端基础-CSS基础选择器
CSS选择器(重点) 理解 能说出选择器的作用 id选择器和类选择器的区别 1. CSS选择器作用(重点) 如上图所以,要把里面的小黄人分为2组,最快的方法怎办? 很多, 比如 一只眼睛的一组,剩下的 ...
- CMDB项目要点之技术点(面试题)
1.单例模式 日志对象用单例模式 django admin中注册类是,用到单例模式 为什么要用单例模式 同一个对象操作 维护全局变量 + 对全局变量做一些操作 # __new__ import thr ...
- 微服务网关Zuul过滤器Filter
Zuul本质 Zuul是一个网关,关于网关的介绍参考:亿级流量架构之网关设计思路.常见网关对比, 可知Zuul是一个业务网关, 而深入了解Zuul, 基本就是一系列过滤器的集合: Zuul的过滤器 下 ...
- Python-tkinter-window
示例代码讲解 1.加载tkinter模块 2.创建一个窗口 3.设置窗口的主题 4.开始窗口的事件循环 import tkinter 2 win = tkinter.Tk() 3 win.title( ...
- 基础篇:JAVA引用类型和ThreadLocal
前言 平时并发编程,除了维护修改共享变量的场景,有时我们也需要为每一个线程设置一个私有的变量,进行线程隔离,java提供的ThreadLocal可以帮助我们实现,而讲到ThreadLocal则不得不讲 ...
- P1200_你的飞碟在这儿(JAVA语言)
题目描述 众所周知,在每一个彗星后都有一只UFO.这些UFO时常来收集地球上的忠诚支持者. 不幸的是,他们的飞碟每次出行都只能带上一组支持者.因此,他们要用一种聪明的方案让这些小组提前知道谁会被彗星带 ...
- 「HTML+CSS」--自定义按钮样式【004】
前言 Hello!小伙伴! 首先非常感谢您阅读海轰的文章,倘若文中有错误的地方,欢迎您指出- 哈哈 自我介绍一下 昵称:海轰 标签:程序猿一只|C++选手|学生 简介:因C语言结识编程,随后转入计算机 ...
- 冒泡算法(BubbleSort)
/*冒泡排序原理 比较相邻的元素.如果前一个元素比后一个元素大,就交换这两个元素的位置. 对每一对相邻元素做同样的工作,从开始第一对元素到结尾的最后一对元素.最终最后位置的元素就是最大值.实现步骤 1 ...