uva 11624 Fire!(bfs预处理)

http://acm.sdut.edu.cn:8080/vjudge/contest/view.action?cid=116#problem/A

题意:帮助joe走出一个大火蔓延的迷宫,他每分钟可以走上下左右四个方向之一,而所有着火的格子都会往四周蔓延。joe和火都无法进入障碍格。当joe走到迷宫的边界格子时我们认为他已经走出迷宫.输出joe走出迷宫的最少时间,若无法走出,输出“IMPOSSIBLE”.


思路:两次bfs。因为火是不能熄灭的,当某个格子某时刻着了火,以后会一直着火。所以我们用bfs处理每个格子着火的时刻。在第二次bfs的时候只需判断joe到达该格子的时间是否小于该格子着火的时间即可。

#include <stdio.h>
#include <string.h>
#include <algorithm>
#include <queue>
#include <stack>
#define LL long long
#define _LL __int64

using namespace std;
const int maxn = 1010;
const int INF = 0x3f3f3f3f;
struct node
{
	int x,y;
	int step;
};
queue <node> que;
int dir[4][2] = {{-1,0},{1,0},{0,-1},{0,1}};
int jx,jy;
char map[maxn][maxn],s[maxn];
int time[maxn][maxn],vis[maxn][maxn];
int n,m;
int ans;

//预处理每个格子(不是障碍格)着火的时刻
void solve()
{
	memset(vis,0,sizeof(vis));
	memset(time,INF,sizeof(time));
	while(!que.empty()) que.pop();

	for(int i = 1; i <= n; i++)
	{
		for(int j = 1; j <= m; j++)
			if(map[i][j] == 'F')
			{
				que.push((struct node){i,j,1});
				time[i][j] = 1;
				vis[i][j] = 1;
			}
	}

	while(!que.empty())
	{
		struct node u = que.front();
		que.pop();

		for(int d = 0; d < 4; d++)
		{
			int x = u.x + dir[d][0];
			int y = u.y + dir[d][1];
			if(x >= 1 && x <= n && y >= 1 && y <= m && map[x][y] != '#' && !vis[x][y])
			{
				vis[x][y] = 1;
				que.push((struct node){x,y,u.step+1});
				time[x][y] = u.step+1;
			}
		}
	}
}

//寻找joe出口的最短路径
bool bfs()
{
	memset(vis,0,sizeof(vis));
	while(!que.empty()) que.pop();

	vis[jx][jy] = 1;
	que.push((struct node){jx,jy,1});

	while(!que.empty())
	{
		struct node u = que.front();
		que.pop();

		if(u.x == 1 || u.x == n || u.y == 1 || u.y == m)
		{
			ans = u.step;
			return true;
		}

		for(int d = 0; d < 4; d++)
		{
			int x = u.x + dir[d][0];
			int y = u.y + dir[d][1];
			if(x >= 1 && x <= n && y >= 1 && y <= m && map[x][y] != '#' && !vis[x][y])
			{
				if(u.step + 1 < time[x][y]) //只有当该格子没着火才进队列
				{
					time[x][y] = 1;
					que.push((struct node){x,y,u.step+1});
				}
			}
		}
	}
	return false;
}

int main()
{
	int test;
	scanf("%d",&test);
	while(test--)
	{
		scanf("%d %d",&n,&m);
		for(int i = 1; i <= n; i++)
		{
			scanf("%s",map[i]+1);
			for(int j = 1; j <= m; j++)
				if(map[i][j] == 'J')
				{
					jx = i;
					jy = j;
				}
		}

		solve();
		if(bfs())
			printf("%d\n",ans);
		else printf("IMPOSSIBLE\n");

	}
	return 0;
}


你可能感兴趣的:(bfs)