UVA - 11624 Fire!(多源BFS)

题目传送门

//#include <bits/stdc++.h>
#include <iostream>
#include <stdio.h>
#include <queue>
#include <algorithm>
#include <fstream>
#define MAXN 1010
#define INF 0x3f3f3f
using namespace std;
int nex[4][2] = {{1, 0}, {0, 1}, {-1, 0}, {0, -1}};
char mmp[MAXN][MAXN];
int tim[MAXN][MAXN];
struct Node
{
    int x;
    int y;
    int layer;
};
int main(void)
{
	int T;
	//ofstream fout("D:\\out.txt");
	scanf("%d", &T);
	while (T--) {
		int R, C;
		int startx, starty;

		queue<Node> people;//人可以走的地方
		queue<Node> fire;//用以统计每个点着火的时间

		scanf("%d%d", &R, &C);
		Node temp;
		for (int i = 0; i < R; i++)cin >> mmp[i];
		for (int i = 0; i < R; i++)
			for (int j = 0; j < C; j++) {
				if (mmp[i][j] == '.')tim[i][j] = INF;
				else if (mmp[i][j] == 'J') {
					tim[i][j] = INF;//起点
					people.push(Node{ i, j, 0 });
				}
				else if (mmp[i][j] == 'F') {
					tim[i][j] = 0;//着火点
					fire.push(Node{ i, j, 0 });
				}
				else if (mmp[i][j] == '#') { tim[i][j] = -1; }//墙
			}
		temp = people.front();
		if (temp.x == 0 || temp.y == 0 || temp.x == R - 1 || temp.y == C - 1)
		{//第一次WA的地方,如果起点在边缘直接输出1
			printf("1\n");
			//fout << 1 << endl;
			continue;
		}
		while (!fire.empty())
		{//计算地图每个地方着火的时间
			for (int i = 0; i < 4; i++)
			{
				int tx = fire.front().x + nex[i][0];
				int ty = fire.front().y + nex[i][1];
				int ttim = fire.front().layer;

				if (tx >= 0 && tx < R&&ty >= 0 && ty < C&&tim[tx][ty] == INF)
				{
					tim[tx][ty] = ttim + 1;
					fire.push(Node{ tx, ty, ttim + 1 });
				}
			}
			fire.pop();
		}
		bool ok = false;
		int ans = 0;

		while (!people.empty())
		{//人开始走了
			for (int i = 0; i < 4; i++)
			{
				int tx = people.front().x + nex[i][0];
				int ty = people.front().y + nex[i][1];
				int dist = people.front().layer + 1;

				if ((tx == 0 || tx == R - 1 || ty == 0 || ty == C - 1) && mmp[tx][ty] == '.'&&dist < tim[tx][ty])
				{//走到边界之后
					ok = true;
					ans = dist;
					break;
				}
				if (tx > 0 && tx < R - 1 && ty>0 && ty < C - 1 && mmp[tx][ty] == '.'&&dist < tim[tx][ty])
				{//没有走到边界
					people.push(Node{ tx, ty, dist });
					mmp[tx][ty] = '+';
				}
			}
			if (ok)break;
			people.pop();
		}
		if (ok)
		{
			printf("%d\n", ans + 1); 
			//fout << ans + 1 << endl;
		}
		else
		{
			printf("IMPOSSIBLE\n");
			//fout << "IMPOSSIBLE" << endl;
		}
	}
	//system("pause");

	return 0;
}

 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值