UVA11642.Fire!(两次BFS)

题解:火的数目不一定唯一,所以遍历地图将火的位置加入队列,bfs1数组搜索火达到某一点的时间,
然后用bfs搜索如何出去,当到达某一点如果_time不为INF那么如果step大于time,那么火已经到达这一点,不能加入队列,如果time为INF那么可以到达,直到走出迷宫,或者走不出去

#include<iostream>
#include<algorithm>
#include<cstdio>
#include<cmath>
#include<string>
#include<queue>
#include<cstring>
#include<stack>
#include<vector>
using namespace std;

const int INF = 0x3f3f3f3f;
int n, m,t;
int bx, by;
int vis[1010][1010];
int _time[1010][1010];
char map[1010][1010];
int dir[4][2] = { 0, 1, 0, -1, 1, 0, -1, 0 };

bool checkedge(int x,int y){
	if (map[x][y] == '#' || x<1 || x>n || y<1 || y>m || vis[x][y])
		return 1;
	return 0;
}
struct node{
	int x, y;
	int step;
};
queue<node>q;
void bfs1(){//记录火达到某一点的时间
	while (!q.empty()){
		node now = q.front();
		q.pop();
		int nx, ny;
		for (int i = 0; i < 4; i++){
			nx = now.x + dir[i][0];
			ny = now.y + dir[i][1];
			if (checkedge(nx, ny)) continue;
			_time[nx][ny] = _time[now.x][now.y] + 1;
			vis[nx][ny] = 1;
			q.push({ nx, ny, now.step + 1 });
		}
	}
}
void bfs(int x, int y){//bfs走迷宫就行
	node now;
	now.x = x;
	now.y = y;
	now.step = 0;
	q.push(now);
	vis[x][y] = 1;
	while (!q.empty()){
		now = q.front();
		q.pop();
		if (now.x == 1 || now.y == 1 || now.x == n || now.y == m){
			cout << now.step + 1 << endl;
			return;
		}
		int nx, ny;
		for (int i = 0; i < 4; i++){
			nx = now.x + dir[i][0];
			ny = now.y + dir[i][1];
			if (map[nx][ny] == '#' || vis[nx][ny] || (now.step + 1) >= _time[nx][ny])//火先到达
				continue;
			vis[nx][ny] = 1;
			q.push({ nx, ny, now.step + 1 });
		}
	}
	cout << "IMPOSSIBLE" << endl;//走不出来
	return;
}
int main(){
	ios::sync_with_stdio(false);
	cin >> t;
	while (t--){
		cin >> n >> m;
		memset(vis, 0, sizeof vis);
		memset(_time, 0x3f, sizeof _time);
		for (int i = 1; i <= n; i++)
			cin >> map[i] + 1;
		for (int i = 1; i <= n; i++)
			for (int j = 1; j <= m; j++){
				if (map[i][j] == 'J')
					bx = i, by = j;
				if (map[i][j] == 'F'){
					q.push({ i, j, 0 });//如果为火加入队列,然后搜时间
					_time[i][j] = 0;//初始化
					vis[i][j] = 1;
				}
			}
		bfs1();
		while (!q.empty()) q.pop();//清空
		memset(vis, 0, sizeof vis);//初始化
		bfs(bx, by);
	}
	return 0;
}
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值