uva 11624 大火蔓延的迷宫 Fire!(两次bfs)



题目:一个平面迷宫中有一个人,迷宫中有些点起火了,火和人每个单位时间只能向相邻的格子移动,

其中有一些空间被墙壁占据,问这个人在不背或烧到的情况下,离开迷宫的最快时间。

思路是先用bfs预处理每个格子起火的时间,在来一次bfs走迷宫,入队时判断着火事件和父节点时间大小关系

代码如下:

#include<cstdio>
#include<cstring>
#include<cmath>
#include<cstdlib>
#include<iostream>
#include<algorithm>
#include<vector>
#include<map>
#include<queue>
#include<stack>
#include<string>
#include<map>
#include<set>
using namespace std;
#define LL long long  

const int maxr = 1000 + 5;
const int maxc = 1000 + 5;
const int dirx[] = {-1, 0, 1, 0};
const int diry[] = {0, -1, 0, 1};
const int INF = 100000000;

struct node {
	int x; int y;
};

int G[maxr][maxc], fire_time[maxr][maxc], timeuse[maxr][maxc];
//0表示障碍,1表示空地,2表示着火 

void bfs(int r, int c) {
	queue<node> fire;
	for(int i = 1; i <= r; i++)
		for(int j = 1; j <= c; j++) {
			fire_time[i][j] = INF;
			if(G[i][j] == 2) {
				fire_time[i][j] = 0;
				fire.push((node){i, j});
			}
		}

	while(!fire.empty()) {
		node f = fire.front(); fire.pop();
		for(int i = 0; i < 4; i++) {
			int nx = f.x + dirx[i], ny = f.y + diry[i];
			if(nx > 0 && nx <= r && ny > 0 && ny <= c && G[nx][ny] == 1 && fire_time[nx][ny] == INF) {
				fire_time[nx][ny] = fire_time[f.x][f.y] + 1;
				fire.push((node){nx, ny});
			}
		}
	}
} 

void bfs_mg(int jx, int jy, int r, int c) {
	for(int i = 1; i <= r; i++)
		for(int j = 1; j <= c; j++) timeuse[i][j] = INF;
	queue<node> mg;
	timeuse[jx][jy] = 0;
	mg.push((node){jx, jy});

	while(!mg.empty()) {
		node u = mg.front(); mg.pop();
		for(int i = 0; i < 4; i++){
			int nx = u.x + dirx[i];
			int ny = u.y + diry[i];
			if(nx > 0 && nx <= r && ny > 0 && ny <= c && G[nx][ny] == 1 && timeuse[nx][ny] == INF && timeuse[u.x][u.y] < fire_time[nx][ny] - 1){
				timeuse[nx][ny] = timeuse[u.x][u.y] + 1;
				mg.push((node){nx, ny});
			}
		}
	}
}

void solve(int r, int c){
	int ans = INF;
	for(int i = 1; i <= r; i++)
		ans = min(ans, timeuse[i][1]);
	for(int i = 1; i <= r; i++)
		ans = min(ans, timeuse[i][c]);
	for(int j = 1; j <= c; j++)
		ans = min(ans, timeuse[1][j]);
	for(int j = 1; j <= c; j++)
		ans = min(ans, timeuse[r][j]);
	if(ans == INF) printf("IMPOSSIBLE\n");
	else printf("%d\n", ans + 1);
}

int main() {
	//freopen("input.txt", "r", stdin);
	int t; scanf("%d", &t);
	while(t--) {
		int r, c; scanf("%d%d", &r, &c);
		int jx, jy;
		for(int i = 1; i <= r; i++) {
			getchar();
			for(int j = 1; j <= c; j++)	{
				char x; scanf("%c", &x);
				if(x == '#') G[i][j] = 0;
				else if(x == '.') G[i][j] = 1;
				else if(x == 'F') G[i][j] = 2;
				else {G[i][j] = 0; jx = i; jy = j;}
			}
		}

		bfs(r, c);
		bfs_mg(jx, jy, r, c);

		solve(r, c);

		//for(int i = 1; i <= r; i++)
		//	for(int j = 1; j <= c; j++) printf("%d ", fire_time[i][j]);
		//for(int i = 1; i <= r; i++)
		//	for(int j = 1; j <= c; j++) printf("%d ", time[i][j]);
		//for(int i = 1; i <= r; i++)
		//	for(int j = 1; j <= c; j++) printf("%d ", G[i][j]);
	}
	return 0;
}
时间: 2024-10-12 23:57:54

uva 11624 大火蔓延的迷宫 Fire!(两次bfs)的相关文章

UVa 11624 大火蔓延的迷宫

https://vjudge.net/problem/UVA-11624 题意:有一个大火蔓延的迷宫,迷宫中有障碍格,而所有着火的格子都会往四周蔓延.求出到达边界格子时的最短时间. 思路:复杂了一点的迷宫. 在bfs之前,我们首先需要计算出火势蔓延的情况,火势每次向四周蔓延一个格子,所以这也是一个最短路问题,也用一次bfs,计算出每个空白格子着火时的时间.这样,当我们第二次bfs去计算走出迷宫的时间时,对于每一个可走的格子,我们只需要判断在此时该格子是否着火,如果还未着火,则该格子是可以走的.

uva11624 - Fire! 两次bfs

题目链接 Problem B: Fire! Joe works in a maze. Unfortunately, portions of the maze have caught on fire, and the owner of the maze neglected to create a fire escape plan. Help Joe escape the maze. Given Joe's location in the maze and which squares of the

uva 11624 Fire!(多源BFS)

uva 11624 Fire! 题目大意:J在迷宫里工作,有一天迷宫起火了,火源有多处.每过一秒,火源都会向四个方向蔓延,J也会向四个方向移动,问J能不能跑出去,能的话输出他跑出去的最短时间,否则输出"IMPOSSIBLE" 解题思路:先进行一次BFS,找出每一点火焰蔓延到该处的最短时间.然后根据这张"火势图",对J的行进路线进行BFS.注意J在边缘的时候,以及没有火源的时候. #include <cstdio> #include <cstring

UVa 11624 Fire!(着火了!)

p.MsoNormal { margin: 0pt; margin-bottom: .0001pt; text-align: justify; font-family: "Times New Roman"; font-size: 10.5000pt } h3 { margin-top: 5.0000pt; margin-bottom: 5.0000pt; text-align: left; font-family: 宋体; font-weight: bold; font-size: 1

UVA 11624 - Fire!(BFS)

UVA 11624 - Fire! 题目链接 题意:一个迷宫,一些格子着火了,火每秒向周围蔓延,现在J在一个位置,问他能走出迷宫的最小距离 思路:BFS2次,第一次预处理每个位置着火时间,第二次根据这个再BFS一次 代码: #include <cstdio> #include <cstring> #include <queue> using namespace std; const int d[4][2] = {0, 1, 1, 0, 0, -1, -1, 0}; co

BFS(两点搜索) UVA 11624 Fire!

题目传送门 1 /* 2 BFS:首先对火搜索,求出火蔓延到某点的时间,再对J搜索,如果走到的地方火已经烧到了就不入队,直到走出边界. 3 */ 4 /************************************************ 5 Author :Running_Time 6 Created Time :2015-8-4 8:11:54 7 File Name :UVA_11624.cpp 8 ****************************************

UVA 11624 UVA 10047 两道用 BFS进行最短路搜索的题

很少用bfs进行最短路搜索,实际BFS有时候挺方便得,省去了建图以及复杂度也降低了O(N*M): UVA 11624 写的比较挫 #include <iostream> #include <cstdio> #include <cstring> #include <queue> using namespace std; struct node{ int ft; int sta; }flo[1010][1010]; int vis[1010][1010]; st

J - Fire!---UVA 11624

题目链接 题意:J代表Joe的位置,F代表火的起点,下一刻火将会向四周扩散,求Joe逃离的最短时间,如果不能逃离输出IMPOSSIBLE; 注意火的起点可能不止一处 可以用两次bfs分别求出人到达某个位置所用时间和火到达某个位置所用时间 1 #include<iostream> 2 #include<stdio.h> 3 #include<string.h> 4 #define INF 0xfffffff 5 #include<queue> 6 #inclu

BFS Fire! UVA - 11624

在一个矩形方阵里面,一个人要从一个位置走向另一个位置,其中某些地方有火源,每过一分钟,火源就会点燃相邻的点,同时相邻的点也变成了火源.人不能通过有火的点.问一个人能够安全地走到边界去最短时间多少?Unfortunately, portions of the maze havecaught on fire.portions of 是一些的意思. 两次bfs,首先从着火的点开始BFS进行预处理,在BFS求最短路. #include<iostream> #include<cstdio>