优先队列版bfs maze

链接:登录—专业IT笔试面试备考平台_牛客网
题目描述:

输入:
5 5 1

..S..

.....

.###.

.....

..T..

1 2 3 3

5 5 1

..S..

.....

.###.

.....

..T..

3 3 1 2

5 5 1

S.#..

..#..

###..

.....

....T

0 1 0 2

4 4 2

S#.T

.#.#

.#.#

.#.#

0 0 0 3

2 0 2 2

输出:

6
8
-1
3

这道题跟普通dfs的区别就在于,它是有一个传送门的,那么当然不能像普通dfs一样建立一个队列,然后无脑塞进去再拿出来,因为我们塞进去的可能是通过传送门到达的地方,而dfs建队列的原则是先进入队列的一定是离起点最近的,那么传送门所带来的距离的不确定性就让我们无法正常使用queue。

但是再一想,我们关心的其实不是进入队列的顺序,因为它最终要影响的其实是出队的顺序,而出队的顺序,由该点距离起点的距离决定,既然如此,就可以建一个优先队列来存储,我们依然可以无脑塞进去,因为优先队列可以保证我们的距离始终有序。

另一个问题是如何存储传送门的起点和终点。显然,用一个vector建立邻接表就可以了。

关于优先队列的排序,我们要以到起点的距离为标准,所以可以建一个结构体,存放步数,步数就是排序的标准。

代码:

#include<bits/stdc++.h>
using namespace std;
int n,m,q;
struct ty{//建立结构体
	int x,y,step;
	bool operator<(const ty& s)const{
		return step>s.step;//重载<符号
	}
};
bool vis[310][310];//标记是否走过
ty star,ed;//起终点
int dir[][4]={{1,0},{-1,0},{0,1},{0,-1}};
char mas[310][310];
vector<int> v[90010];//用一个数来存二维信息,故开一个int就可以了
bool inmap(int x,int y){
	return x>=0&&y>=0&&x<n&&y<m;
}
void bfs(){
	memset(vis,0,sizeof(vis));
	priority_queue<ty> q;
	q.push(star);
	vis[star.x][star.y]=1;
	while(!q.empty()){
		ty t=q.top();
		q.pop();
		int x=t.x,y=t.y;
		if(mas[x][y]=='T') {cout<<t.step<<endl;return;}
		for(int i=0;i<4;++i){
			int xx=x+dir[i][0];
			int yy=y+dir[i][1];
			if(inmap(xx,yy)&&!vis[xx][yy]&&mas[xx][yy]!='#'){
				vis[xx][yy]=1;
				q.push({xx,yy,t.step+1});	
			}
		}
		for(int i:v[x*n+y]){
			int a=i/n;
			int b=i%n;
			if(inmap(a,b)&&mas[a][b]!='#'&&!vis[a][b]){
				vis[a][b]=1;
				q.push({a,b,t.step+3});
			}
		}
	} 
	cout<<-1<<endl;
}
int main()
{ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
	while(cin>>n>>m>>q){
		for(int i=0;i<n;++i){
			for(int j=0;j<m;++j){
				cin>>mas[i][j];
				v[i*n+j].clear();//清空vector,因为有多组样例!
				if(mas[i][j]=='S') star={i,j};
				if(mas[i][j]=='T') ed={i,j};
			}
		}
		for(int i=1;i<=q;++i){
			ty s1,s2;
			cin>>s1.x>>s1.y>>s2.x>>s2.y;
			v[(s1.x)*n+s1.y].push_back((s2.x)*n+s2.y);
		}
		bfs();
	}
	return 0;
}

因为是多组样例,要特别注意相关定义的清空包括vector、priority_queue、vis等。细节没有太多,跟普通dfs相比只是改了一个优先队列而已。

一道相关的题(状态更加复杂一些,要对vis进行变化)

优先队列+bfs why的吃鸡_sophilex的博客-CSDN博客

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值