BFS【古希腊之争(二)】(bfs+优先队列)
题目描述
话说,年轻的斯巴达勇士们终于走出迷宫,取得胜利并顺利赶了回来。可是等他们回到斯巴达的时候才发现,雅典人趁他们不在偷袭了城邦,并抓走了他们的爱人。侥幸逃出来的几个人说,她们被关押在一个迷宫的牢房里,并把关押她们的迷宫里的情况告诉了年轻的勇士:迷宫中的”S”点表示迷宫的入口,”T”点表示迷宫中牢房的位置,”.”表示空地,可以通过,”#”表示墙,不能直接通过,”K”表示陷阱,一旦进入就必死无疑。每次只能向上下左右四个方向移动,每移动一个单位距离需要耗费一个单位时间,所有斯巴达勇士的移动速度相同。
又是迷宫!!!这次斯巴达的勇士们彻底愤怒了!What’s more, today is the Magpie Festival!
由于斯巴达的勇士们无比愤怒,而且她们也想尽可能的在今天就能救出他们的爱人。所以当他们在迷宫中遇到墙的阻碍时,也能破墙进入。不过破墙的过程会花费一个单位的时间。现在请你计算一下他们最短需要多少时间才能找到迷宫的牢房。
PS:假设迷宫中每个点可以容纳的人数没有限制,每个斯巴达勇士的行动方向之间没有影响。
输入格式
每组测试数据第一行输入二个数n,m(2=<m<=n<=100)分别代表迷宫的长度和宽度。下面n行每行有m个字符用来表示迷宫地图。
0 0表示输入结束,详细输入格式见样例。
输出
输出一个整数,表示找到迷宫出口的最短时间,每组输出占一行。如不能找到出口输入-1
样例输入
3 4
S#.#
..K.
KKT.
0 0
样例输出
8
STL 中优先队列的使用方法(priority_queu)
优先队列容器与队列一样,只能从队尾插入元素,从队首删除元素。但是它有一个特性,就是队列中最大的元素总是位于队首,所以出队时,并非按照先进先出的原则进行,而是将当前队列中最大的元素出队。这点类似于给队列里的元素进行了由大互小的顺序排序。元素的比较规则默认按元素值由大到小排序,可以重载“<”操作符来重新定义比较规则。
基本操作:
empty() 如果队列为空返回真
pop() 删除对顶元素
push() 加入一个元素
size() 返回优先队列中拥有的元素个数
top() 返回优先队列对顶元素
在默认的优先队列中,优先级高的先出队。在默认的int型中先出队的为较大的数。
使用方法:
头文件:
#include <queue>
声明方式:
1、普通方法:
priority_queue<int>q; //通过操作,按照元素从大到小的顺序出队
priority_queue<int,vector<int>, greater<int> >q; //通过操作,按照元素从小到大的顺序出队
2、自定义优先级:
struct cmp {
operator bool ()(int x, int y)
{
return x > y; // x小的优先级高 //也可以写成其他方式,如: return p[x] > p[y];表示p[i]小的优先级高
}
};
priority_queue<int, vector<int>, cmp>q; //定义方法
//其中,第二个参数为容器类型。第三个参数为比较函数。
3、结构体声明方式:
struct node {
int x, y;
friend bool operator < (node a, node b)
{
return a.x > b.x; //结构体中,x小的优先级高
}
};
priority_queue<node>q; //定义方法
//在该结构中,y为值, x为优先级。
//通过自定义operator<操作符来比较元素中的优先级。
//在重载”<”时,最好不要重载”>”,可能会发生编译错误
内容来自:https://www.cnblogs.com/yaoyueduzhen/p/4456430.html
原来的迷宫bfs 先让最近一圈(1)的入列,再从第一个入列的最近一圈找点入列,再在(1)最近一圈找点入列。
而这道题涉及到了不同的权值,什么意思?原来的题(比如古希腊之争(一))的每个点的前进都是1个权值,所有前进的点的权值是一样的,随意的入队出队顺序不会影响。而这题有了破墙,也就是有的点前进权值是2,有的点前进权值是1,在这样的入列出列中找到去终点的权值最小的一条。所以我们要通过一定的手段去调整入队出队的顺序。
举例子图:![](/assets/blank.gif)
然后我们用代码来实现:优先队列的重载我们看上面的知识点 一些需要注意的地方看的代码注释
其中bfs的最后需要是return-1,不然的话在这个代码中刚开始初始化为0,再用now.t去更新,如果找不到出口的话不能输出-1。 并且如果起点终点重合的话直接输出初始化的0就可以了
#include<stdio.h>
#include<string.h>
#include<algorithm>
#include<iostream>
#include<queue>
using namespace std;char a[100][100];
int vis[100][100];
int sx,sy,fx,fy;
int dx[4]={1,0,-1,0};
int dy[4]={0,1,0,-1};
int n,m;struct node{int x;int y;int t; //t记录步数 friend bool operator <(node c,node d) ///重载时最好用< {return c.t>d.t; 如果a.t>b.t 则认为a<b }}; int bfs()
{priority_queue<node>que;node now,next;now.x=sx,now.y=sy,now.t=0;que.push(now);vis[sx][sy]=0;while(que.size()){now=que.top();que.pop();if(now.x==fx&&now.y==fy){return now.t;}for(int i=0;i<4;i++){int nx=now.x+dx[i];int ny=now.y+dy[i];if(nx>=0&&nx<n&&ny>=0&&ny<m&&vis[nx][ny]==-1&&a[nx][ny]!='K'){next.x=nx;next.y=ny;// que.push(next);vis[nx][ny]=0;if(a[nx][ny]=='#')next.t=now.t+2;if(a[nx][ny]=='.'||a[nx][ny]=='T')next.t=now.t+1;que.push(next);///在确定了接下来的步数后再入优先队列}}}return -1; 如果达不到终点要输出-1
}int main(void)
{while(scanf("%d%d", &n, &m)!=EOF){if(n==0&&m==0) break;memset(vis,-1,sizeof(vis));memset(a,'\0',sizeof(a));for(int i=0;i<n;i++)cin>>a[i];for(int i=0;i<n;i++){for(int j=0;j<m;j++){if(a[i][j]=='S')sx=i,sy=j;if(a[i][j]=='T')fx=i,fy=j;}}int res=bfs();if(res==-1)printf("-1");else if(res!=-1)printf("%d\n",res);}
return 0;
}
BFS【古希腊之争(二)】(bfs+优先队列)相关推荐
- 广度优先搜索BFS进阶(一):多源BFS、优先队列BFS、双端队列BFS
一.多源BFS 在上一篇博客:广度优先搜索BFS基础中,我们接触到的BFS均是单起点(单源)的,但是对于某一些问题,其有多个起点,此类问题我们称为多源BFS问题.先思考下面一道例题: 1.腐烂的橘子 ...
- 二叉树中进行 BFS 和图中进行 BFS 最大的区别
二叉树中进行 BFS 和图中进行 BFS 最大的区别 就是二叉树中无需使用 HashSet(C++: unordered_map, Python: dict) 来存储访问过的节点(丢进过 queue ...
- BFS【古希腊之争(二)】
题目描述 话说,年轻的斯巴达勇士们终于走出迷宫,取得胜利并顺利赶了回来.可是等他们回到斯巴达的时候才发现,雅典人趁他们不在偷袭了城邦,并抓走了他们的爱人.侥幸逃出来的几个人说,她们被关押在一个迷宫的牢 ...
- 问题 E: 古希腊之争(一)(bfs迷宫裸模板)
时间限制: 1 Sec 内存限制: 128 MB 提交: 138 解决: 52 [提交] [状态] [讨论版] [命题人:外部导入] 题目描述 伯罗奔尼撒战争是以雅典为首的提洛同盟与以斯巴达为首的 ...
- bfs(图的最短路径)+优先队列 (2021-8-9)
刺客信条 题意 小A就将操控艾吉奥从佛罗伦萨庄园出发,前往梵蒂冈,夺取教皇权杖. 在整个过程中,每经过一个建筑,都需要花费一定的时间,需要特别注意的是,由于圣母百花大教堂.圣马可大教堂.乔托钟楼都有众 ...
- bfs算法 c语言,基于BFS算法的贪吃蛇(一)----基本架构
先上成品图: 承接简单贪吃蛇C语言版高级版(一):基本框架搭建,上一篇文章是基于二维地图设计的基本框架,但是在后续的编写中发现在简单的模型下使用二维地图会让一个语句非常的长,耐读性不强.但是在复杂的情 ...
- [Leetcode][第111题][JAVA][BFS][二叉树的最小深度][BFS][递归]
[问题描述][简单] [解答思路] 1. 递归 自下而上 基本情况/结束条件 : 叶子节点的定义是左孩子和右孩子都为 null 时叫做叶子节点 当 root 节点左右孩子都为空时,返回 1 当 roo ...
- Valid BFS? CodeForces - 1037D(思维 bfs)
我真是一只菜狗......emm... 题意: 判断一个从1开始的队列是否可以按照bfs的顺序 进行遍历..必须从1开始...然后后边依次是bfs顺序 解析: 看代码能看懂吧...emm...就是把每 ...
- 第十四届华中科技大学程序设计竞赛-L—Fresh Air,bfs拓展,倒着bfs
链接: https://www.nowcoder.com/acm/contest/106/L 来源:牛客网 It's universally acknowledged that there're in ...
最新文章
- php 判定pc端與移動端
- 那年大一在图书馆作死的大学高数笔记 | 函数和极限
- 机器学习 —— python库 —— 使用array创建
- Asp.Net Core使用Skywalking实现分布式链路追踪
- C语言深度剖析书籍学习记录 第四章 指针和数组
- 阿里云POLARDB如何帮助百胜软件应对数据库的“巅峰时刻”
- MySQL中处理Null时要注意两大陷阱
- 详解Java类对象执行顺序
- 支付宝解释 2019 年账单总额较高;腾讯 QQ 回应新功能可显示对方实时电量;Python 2.7 结束支持 | 极客头条...
- 如何用PS软件取得色块的颜色值?
- python海龟绘图代码大全-编程入门06:Python海龟绘图
- 纯CSS3代码制作六边形图形教程
- Linux入门基础命令教程
- XCode 动态库未签名问题的解决
- OkHttp系列——使用教程
- c语言编文曲星游戏,关于汉诺塔游戏的思路(就是最早文曲星上移盘子的那个)...
- 软考网络工程师协议和名称---必看
- Facebook投资者Peter Thiel—一个不折不扣的“魔戒”迷
- 计算机网络安全(三)
- ogre3D学习基础4 -- 网格工具与硬件缓存
热门文章
- Java 锁相关知识汇总及锁升级
- iDNA-ABF:DNA甲基化可解释预测的多尺度深度生物语言学习模型
- Photoshop人像修图教程汇总和photoshop修图技巧汇集
- linux安装git指定版本
- Cocos Creator 3.1 携多线程渲染架构和 PhysX 物理支持强势登场
- standard python venv module_Python venv ModuleNotFoundE
- 高德地图多边形地图的设置
- 1019: 谁是老二(结构体)
- Jerry Ma:期货市场反转的三个重要标志
- 控制台的html如何复制,如何复制css代码