ZOJ Problem Set - 1649 - Rescue

  ZOJ Problem Set - 1649 -  Rescue

Angel was caught by the MOLIGPY! He was put in prison by Moligpy. The prison is described as a N * M (N, M <= 200) matrix. There are WALLs, ROADs, and GUARDs in the prison.

Angel's friends want to save Angel. Their task is: approach Angel. We assume that "approach Angel" is to get to the position where Angel stays. When there's a guard in the grid, we must kill him (or her?) to move into the grid. We assume that we moving up, down, right, left takes us 1 unit time, and killing a guard takes 1 unit time, too. And we are strong enough to kill all the guards.

You have to calculate the minimal time to approach Angel. (We can move only UP, DOWN, LEFT and RIGHT, to the neighbor grid within bound, of course.)


Input

First line contains two integers stand for N and M.

Then N lines follows, every line has M characters. "." stands for road, "a" stands for Angel, and "r" stands for each of Angel's friend.

Process to the end of the file.


<b< dd="">

Output

For each test case, your program should output a single integer, standing for the minimal time needed. If such a number does no exist, you should output a line containing "Poor ANGEL has to stay in the prison all his life."


<b< dd="">

Sample Input

7 8 
#.#####. 
#.a#..r. 
#..#x... 
..#..#.# 
#...##.. 
.#...... 
........


<b< dd="">

Sample Output

13



分析:这道题与普通的BFS迷宫题不一样,这里有障碍!每碰到一个守卫guard就要多花费一分钟,这就导致BFS搜索遍历时同一层次的花费不同。若是没有守卫,BFS逐层遍历时,每层所花费的时间是相同的,但是现在有守卫,这就导致经过守卫那一格子时时间花费是比同层的其他格子要多的。若继续使用BFS的旧模板这就会导致经过守卫到达angel的最短路径的答案其实不是最短(BFS算法求最短路径只对边权为1时有效)。

此时就得使用priority_queue来确保每次都是选用时间花费最少的路径。

由于priority_queue默认是取最大的元素。而现在需要的是每次取最小的元素,所以需要重载小于<运算符。

代码:

#include<stdio.h>
#include<queue>
#include<cstring>
using namespace std;
int m, n;
int vst[205][205];
char map[205][205];
int dir[4][2] = { 0,1,1,0,-1,0,0,-1 };
struct state {
	int x, y;
	int step;
	friend bool operator<(state a, state b)
	{
		return a.step > b.step;
	}
	//bool operator<(const state &b)const {
	//	return step > b.step;
	//方法2}
}fri,angel;
int check(state now) {
	if (now.x>=0 && now.x<n&&now.y>=0 && now.y<m&&map[now.x][now.y] != '#'&&!vst[now.x][now.y])
		return 1;
	else return 0;
}
int bfs(state st) {
	state now, next;
	priority_queue<state>q;
	vst[st.x][st.y] = 1;
	st.step = 0;
	q.push(st);
	while (!q.empty()) {
		now = q.top();
		if (now.x == angel.x&&now.y == angel.y)
			return now.step;
		for (int i = 0; i < 4; i++) {
			next.x = now.x + dir[i][0];
			next.y = now.y + dir[i][1];
			if (check(next)) {
				next.step = now.step + 1;
				if (map[next.x][next.y] == 'x')
					next.step++;
				q.push(next);
				vst[next.x][next.y] = 1;
			}
		}
		q.pop();
	}
	return -1;
}
int main(void) {
	while (~scanf("%d%d", &n, &m)) {
		memset(vst, 0, sizeof vst);
		memset(map, '\0', sizeof map);
		for (int i = 0; i < n; i++)
			for (int j = 0; j < m; j++)
			{
				scanf(" %c", &map[i][j]);
				if (map[i][j] == 'a')
					angel.x = i, angel.y = j;
				if (map[i][j] == 'r')
					fri.x = i, fri.y = j;
			}
		int c = bfs(fri);
		if (c != -1)
			printf("%d\n", c);
		else
			printf("Poor ANGEL has to stay in the prison all his life.\n");
	}
	return 0;
}


注意一点:

if (map[next.x][next.y] == 'x')
					next.step++;
这段代码判断是否是守卫时,应该是判断next是否是x,而不是now。


猜你喜欢

转载自blog.csdn.net/Titanium_S/article/details/79199714