BFS【古希腊之争(二)】(bfs+优先队列)

题目描述
话说,年轻的斯巴达勇士们终于走出迷宫,取得胜利并顺利赶了回来。可是等他们回到斯巴达的时候才发现,雅典人趁他们不在偷袭了城邦,并抓走了他们的爱人。侥幸逃出来的几个人说,她们被关押在一个迷宫的牢房里,并把关押她们的迷宫里的情况告诉了年轻的勇士:迷宫中的”S”点表示迷宫的入口,”T”点表示迷宫中牢房的位置,”.”表示空地,可以通过,”#”表示墙,不能直接通过,”K”表示陷阱,一旦进入就必死无疑。每次只能向上下左右四个方向移动,每移动一个单位距离需要耗费一个单位时间,所有斯巴达勇士的移动速度相同。
又是迷宫!!!这次斯巴达的勇士们彻底愤怒了!What’s more, today is the Magpie Festival!
由于斯巴达的勇士们无比愤怒,而且她们也想尽可能的在今天就能救出他们的爱人。所以当他们在迷宫中遇到墙的阻碍时,也能破墙进入。不过破墙的过程会花费一个单位的时间。现在请你计算一下他们最短需要多少时间才能找到迷宫的牢房。
PS:假设迷宫中每个点可以容纳的人数没有限制,每个斯巴达勇士的行动方向之间没有影响。
输入格式
每组测试数据第一行输入二个数n,m(2= 0 0表示输入结束,详细输入格式见样例。
输出
输出一个整数,表示找到迷宫出口的最短时间,每组输出占一行。如不能找到出口输入-1
样例输入
3 4
S#.#
..K.
KKT.
0 0
样例输出
8
 


STL 中优先队列的使用方法(priority_queu)

优先队列容器与队列一样,只能从队尾插入元素,从队首删除元素。但是它有一个特性,就是队列中最大的元素总是位于队首,所以出队时,并非按照先进先出的原则进行,而是将当前队列中最大的元素出队。这点类似于给队列里的元素进行了由大互小的顺序排序。元素的比较规则默认按元素值由大到小排序,可以重载“<”操作符来重新定义比较规则。  

基本操作:

empty() 如果队列为空返回真

pop() 删除对顶元素

push() 加入一个元素

size() 返回优先队列中拥有的元素个数

top() 返回优先队列对顶元素

在默认的优先队列中,优先级高的先出队。在默认的int型中先出队的为较大的数。

使用方法:

头文件:

#include 

 

声明方式:

1、普通方法:

priority_queueq;   //通过操作,按照元素从大到小的顺序出队

priority_queue, greater >q;  //通过操作,按照元素从小到大的顺序出队

2、自定义优先级:

struct cmp {     

  operator bool ()(int x, int y)     

  {        

     return x > y; // x小的优先级高       //也可以写成其他方式,如: return p[x] > p[y];表示p[i]小的优先级高

  }

};

priority_queue, cmp>q;    //定义方法

//其中,第二个参数为容器类型。第三个参数为比较函数。

 

3、结构体声明方式:

struct node {     

  int x, y;     

  friend bool operator < (node a, node b)     

  {         

    return a.x > b.x;    //结构体中,x小的优先级高     

  }

};

priority_queueq;   //定义方法

//在该结构中,y为值, x为优先级。

//通过自定义operator<操作符来比较元素中的优先级。

//在重载”<”时,最好不要重载”>”,可能会发生编译错误

内容来自:https://www.cnblogs.com/yaoyueduzhen/p/4456430.html


原来的迷宫bfs 先让最近一圈(1)的入列,再从第一个入列的最近一圈找点入列,再在(1)最近一圈找点入列。

而这道题涉及到了不同的权值,什么意思?原来的题(比如古希腊之争(一))的每个点的前进都是1个权值,所有前进的点的权值是一样的,随意的入队出队顺序不会影响。而这题有了破墙,也就是有的点前进权值是2,有的点前进权值是1,在这样的入列出列中找到去终点的权值最小的一条。所以我们要通过一定的手段去调整入队出队的顺序。


举例子图:BFS【古希腊之争(二)】(bfs+优先队列)_第1张图片

 


然后我们用代码来实现:优先队列的重载我们看上面的知识点  一些需要注意的地方看////的代码注释  

其中bfs的最后需要是return-1,不然的话在这个代码中刚开始初始化为0,再用now.t去更新,如果找不到出口的话不能输出-1。 并且如果起点终点重合的话直接输出初始化的0就可以了

#include
#include
#include
#include
#include
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 则认为aque;
		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=0&&ny>a[i];

		
		for(int i=0;i

 

你可能感兴趣的:(优先队列,bfs(归类))