http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemCode=1649
做得蛋疼!!!
要注意以下几点:
- cost[i,j]表示friend到[i,j]的代价
- 每次队列最前元素的周围四个元素,都要计算其代价,即使已经被访问过
- 如果出队列的元素是angle,不需要立即break,因为队列中后续元素可能有更小代价
#include <iostream>
#include <vector>
#include <algorithm>
#include <queue>
#include <string.h>
#include <stdio.h>
using namespace std;
#define MAXINT 0x7FFFFFFF
int dx[] = {0, 1, 0, -1};
int dy[] = {-1, 0, 1, 0};
int main()
{
int N, M;
char matrix[200][200];
int cost[200][200];
while (cin >> N >> M)
{
for (int i = 0; i < N; i++)
{
for (int j = 0; j < M; j++)
cin >> matrix[i][j];
getchar();
}
int min = MAXINT;
for (int i = 0; i < N; i++)
for (int j = 0; j < M; j++)
if (matrix[i][j] == 'r') // a friend
{
// initialize
for (int k = 0; k < N; k++)
for (int h = 0; h < M; h++)
cost[k][h] = MAXINT;
// add first one
cost[i][j] = 0;
queue< pair<int, int> > q;
q.push(make_pair<int, int>(i, j));
while (!q.empty())
{
pair<int, int> c = q.front();
q.pop();
if (matrix[c.first][c.second] == 'a')
{
if (cost[c.first][c.second] < min)
min = cost[c.first][c.second];
}
else
{
for (int k = 0; k < 4; k++)
{
int x = c.first + dx[k];
int y = c.second + dy[k];
if (0 <= x && x < N && 0 <= y && y < M && matrix[x][y] != '#')
{
if (cost[x][y] == MAXINT ||
(matrix[c.first][c.second] == 'x' && cost[x][y] > cost[c.first][c.second] + 2) ||
(matrix[c.first][c.second] != 'x' && cost[x][y] > cost[c.first][c.second] + 1))
{
q.push(make_pair<int, int>(x, y));
}
if (matrix[c.first][c.second] == 'x' && cost[x][y] > cost[c.first][c.second] + 2)
{
cost[x][y] = cost[c.first][c.second] + 2;
}
else if (matrix[c.first][c.second] != 'x' && cost[x][y] > cost[c.first][c.second] + 1)
{
cost[x][y] = cost[c.first][c.second] + 1;
}
}
}
}
}
}
if (min == MAXINT)
cout << "Poor ANGEL has to stay in the prison all his life." << endl;
else
cout << min << endl;
}
}