hdu 1044 BFS(压缩图)+DFS
题意:
给你起点,终点,图上有墙有路还有宝物,问你在规定时间内能否能到终点,如果能问最多能捡到多少宝物.
思路:
看完这个题目果断 BFS+三维的mark[][][] 第三维用二进制压缩的思想去解决,结果TLE了,我后来在网上看了看,发现有人用二进制压缩ac了,这更坚定了我的决心啊,不停的优化 超时 优化 超时 就这样我超时了 50多次,我tm恶心了,直接粘了个网上说和我想法一样的代码交上去了,结果 TLE 了, 我 fuck ,超时了早说啊...
,可能是数据加强了.
下面说一下正解 ,观察我们发现,题目中给的宝贝数量并不多,最多才10 ,其实我们可以先 BFS求出所有点的最短路,这些点包括 ,起点,终点,宝物,求完最短路我们其实就把这个图压缩成了最多 10 + 1 + 1 个点,压缩了图之后就是暴力DFS了,12个点压力也有点大,所以要剪枝 , 在深搜的时候如果发现当前的可满足ans 已经等于宝物总和了,那么不用在搜了,直接return 到最外面,或者可以再加上一个就是,当前的所用时间 + 当前到终点的时间
大于题目给的时间限制了,直接return 到上一层;
/*
先BFS把图压缩,在DFS爆搜
*/
#include<stdio.h>
#include<string.h>
#include<queue>
#define N1 60
#define N2 15
using namespace std;
typedef struct
{
int x ,y ,t;
}NODE;
NODE xin ,tou;
int mark_bfs[N1][N1] ,mark_dfs[N2];
int dis[N2][N2] ,money[N2];
int dir[4][2] = {0 ,1 ,0 ,-1 ,1 ,0 ,-1 ,0};
char map[N1][N1];
int xx ,yy ,tt ,mm ,ss ,nn;
bool ok(int x ,int y)
{
if(x >= 0 && x < xx && y >= 0 && y < yy && map[x][y] != '*' && !mark_bfs[x][y])
return 1;
return 0;
}
void BFS(int x ,int y ,int key)// 求那几个点之间的最短路,key当前是起始点.
{
memset(mark_bfs ,0 ,sizeof(mark_bfs));
mark_bfs[x][y] = 1;
xin.x = x ,xin.y = y ,xin.t = 0;
queue<NODE>q;
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(ok(xin.x ,xin.y))
{
mark_bfs[xin.x][xin.y] = 1;
q.push(xin);
if(map[xin.x][xin.y] == '@')
dis[key][0] = xin.t;
if(map[xin.x][xin.y] == '<')
dis[key][nn+1] = xin.t;
if(map[xin.x][xin.y] >= 'A' && map[xin.x][xin.y] <= 'J')
dis[key][map[xin.x][xin.y] - 64] = xin.t;
}
}
}
return ;
}
void DFS(int s ,int time ,int mon) // s是当前点 ,time是当前所用时间,mon是当前财
//富值
{
if(time > tt || mm == ss) return;
if(s == nn + 1 && mm < mon)
mm = mon;
for(int k = 1 ;k <= nn + 1 ;k ++)
{
if(!dis[s][k] || mark_dfs[k]) continue;
mark_dfs[k] = 1;
DFS(k ,time + dis[s][k] ,mon + money[k]);
mark_dfs[k] = 0;
}
}
int main ()
{
int i ,j ,t ,cas = 1;
scanf("%d" ,&t);
while(t--)
{
scanf("%d %d %d %d" ,&yy ,&xx ,&tt ,&nn);
money[0] = money[nn+1] = 0;
for(ss = 0 ,i = 1 ;i <= nn ;i ++)
{
scanf("%d" ,&money[i]);
ss += money[i];
}
for(i = 0 ;i < xx ;i ++)
scanf("%s" ,map[i]);
memset(dis ,0 ,sizeof(dis));
for(i = 0 ;i < xx ;i ++)
for(j = 0 ;j < yy ;j ++)
{
// 起点是 0 ,终点是 n + 1 ,宝物是 1 ---- n其他的墙和路都不要了,深搜时没有用
if(map[i][j] == '*')
continue;
if(map[i][j] == '@')
BFS(i ,j ,0);
if(map[i][j] == '<')
BFS(i ,j ,nn + 1);
if(map[i][j] >= 'A' && map[i][j] <= 'J')
BFS(i ,j ,map[i][j] - 64);
}
mm = -1;
memset(mark_dfs ,0 ,sizeof(mark_dfs));
mark_dfs[0] = 1;
DFS(0 ,0 ,0);
printf("Case %d:\n" ,cas ++);
if(mm == -1)
printf("Impossible\n");
else
printf("The best score is %d.\n" ,mm);
if(t) printf("\n");
}
return 0;
}
hdu 1044 BFS(压缩图)+DFS的更多相关文章
- hdu 1044(bfs+dfs+剪枝)
Collect More Jewels Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Othe ...
- HDU 1983 BFS&&DFS
大多数刚需封锁4区域可以,DFS地区封锁.BFS无论是通过 #include "stdio.h" #include "string.h" #include &q ...
- hdu 1044(bfs+状压)
非常经典的一类题型 没有多个出口.这里题目没有说清楚 Collect More Jewels Time Limit: 2000/1000 MS (Java/Others) Memory Limi ...
- HDU 1044 BFS
Collect More Jewels Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Othe ...
- HDU 1044 Collect More Jewels(BFS+DFS)
Collect More Jewels Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Othe ...
- 列出连通集(DFS及BFS遍历图) -- 数据结构
题目: 7-1 列出连通集 (30 分) 给定一个有N个顶点和E条边的无向图,请用DFS和BFS分别列出其所有的连通集.假设顶点从0到N−1编号.进行搜索时,假设我们总是从编号最小的顶点出发,按编号递 ...
- CF467D Fedor and Essay 建图DFS
Codeforces Round #267 (Div. 2) CF#267D D - Fedor and Essay D. Fedor and Essay time limit per test ...
- HDU 1241 Oil Deposits --- 入门DFS
HDU 1241 题目大意:给定一块油田,求其连通块的数目.上下左右斜对角相邻的@属于同一个连通块. 解题思路:对每一个@进行dfs遍历并标记访问状态,一次dfs可以访问一个连通块,最后统计数量. / ...
- hdu 1241 Oil Deposits(DFS求连通块)
HDU 1241 Oil Deposits L -DFS Time Limit:1000MS Memory Limit:10000KB 64bit IO Format:%I64d & ...
随机推荐
- 精确率precession和召回率recall
假设有两类样本,A类和B类,我们要衡量分类器分类A的能力. 现在将所有样本输入分类器,分类器从中返回了一堆它认为属于A类的样本. 召回率:分类器认为属于A类的样本里,真正是A类的样本数,占样本集中所有 ...
- Shell编程中变量用法
1. 变量替换 语法 说明 ${变量名#匹配规则} 从变量开头进行规则匹配,将符合最短的数据删除 ${变量名##匹配规则} 从变量开头进行规则匹配,将符合最长的数据删除,贪婪匹配 ${变量名%匹配规则 ...
- git的回滚与撤销【reset and revert】
git的工作流程-- 3个区域 工作区:我们可以看到的文件内容 在操作 git add 之前的!! 缓存区:是不可见的 已经git add操作,还没git commit -m "" ...
- Visual Studio添加引用的方式
- 【Azure 服务总线】详解Azure Service Bus SDK中接收消息时设置的maxConcurrentCalls,prefetchCount参数
(Azure Service Bus服务总线的两大类消息处理方式: 队列Queue和主题Topic) 问题描述 使用Service Bus作为企业消息代理,当有大量的数据堆积再Queue或Topic中 ...
- ResNet的个人总结
ResNet可以说是我认真读过的第一篇paper,据师兄说读起来比较简单,没有复杂的数学公式,不过作为经典的网络结构还是有很多细节值得深究的.因为平时不太读英文文献,所以其实读的时候也有很多地方不是很 ...
- Announcing cnblogs-hardening 1.0 Preview 1
Release Notes Write about coding Note About coding Share about coding Talk about coding Comment abou ...
- 【LiteOS】Liteos移植篇
目录 前言 链接 参考 笔录草稿 移植(2018) 移植获取 (Cortex-M 内核) 主要文件夹分析 移植过程 1. 拷贝文件 2. 创建工程分组 3. 添加头文件路径 4. 兼容 C99 模式 ...
- NetCore的缓存使用详例
关于我 作者博客|文章首发 缓存基础知识 缓存可以减少生成内容所需的工作,从而显著提高应用程序的性能和可伸缩性. 缓存最适用于不经常更改的 数据,生成 成本很高. 通过缓存,可以比从数据源返回的数据的 ...
- 普通 Javaweb项目模板的搭建
普通 Javaweb项目模板的搭建 1. 创建一个web项目模板的maven项目 2.配置 Tomcat 服务器 3.先测试一下该空项目 4.注入 maven 依赖 5.创建项目的包结构 6.编写基础 ...