您的位置:首页 > 其它

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

2015-05-15 23:39 471 查看

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

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

思路是先用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;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: