题意:
给一张图,图上a为一个人,x为守卫,杀死守卫要1的单位时间,r为救a的人,注意r可能有很多个。
现在问很多个r来救a,最快多长时间能救出a。
解析:
反过来考虑,由a去找r,找到最近的出来就行了。
为了找到最短的,用优先队列来控制每次最小的点,因为x有的时候会干扰到step的计数,导致不是最短。
代码:
#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <algorithm>
#include <cstring>
#include <cmath>
#include <stack>
#include <vector>
#include <queue>
#include <map>
#define LL long long
#define lson lo, mi, rt << 1
#define rson mi + 1, hi, rt << 1 | 1
using namespace std;
const int maxn = 200 + 10;
const int inf = 0x3f3f3f3f;
const double eps = 1e-6;
const double pi = acos(-1.0);
const double ee = exp(1.0);
int dir[][2] = {{1, 0}, {-1, 0}, {0, 1}, {0, -1}};
int n, m;
int sx, sy;
char g[maxn][maxn];
bool vis[maxn][maxn];
struct Node
{
int x, y, step;
Node(int _x, int _y, int _step)
{
x = _x;
y = _y;
step = _step;
}
bool operator < (const Node& a)const
{
return step > a.step;
}
};
bool ok(int x, int y)
{
if (0 <= x && x < n && 0 <= y && y < m && g[x][y] != '#' && !vis[x][y])
return true;
return false;
}
int bfs()
{
memset(vis, false, sizeof(vis));
priority_queue<Node> q;
q.push(Node(sx, sy, 0));
vis[sx][sy] = true;
while (!q.empty())
{
Node now = q.top();
q.pop();
int x = now.x;
int y = now.y;
int step = now.step;
if (g[x][y] == 'r')
{
return step;
}
for (int i = 0; i < 4; i++)
{
int nx = x + dir[i][0];
int ny = y + dir[i][1];
int nstep = step + 1;
if (ok(nx, ny))
{
if (g[nx][ny] == 'x')
nstep++;
q.push(Node(nx, ny, nstep));
vis[nx][ny] = true;
}
}
}
return -1;
}
int main()
{
#ifdef LOCAL
freopen("in.txt", "r", stdin);
#endif // LOCAL
while (~scanf("%d%d", &n, &m))
{
for (int i = 0; i < n; i++)
{
scanf("%s", g[i]);
}
for (int i = 0; i < n; i++)
{
for (int j = 0; j < n; j++)
{
if (g[i][j] == 'a')
{
sx = i;
sy = j;
}
}
}
int ans = bfs();
if (ans == -1)
printf("Poor ANGEL has to stay in the prison all his life.\n");
else
printf("%d\n", ans);
}
return 0;
}