http://acm.zju.edu.cn/show_problem.php?pid=1671
该题与一般的BFS不同,它可以重复路过某点。因此如何判断可以重复路过某点呢?唯一的情况是路过该点的HP比以前路过该点时要大。
#include <iostream>
#include <vector>
#include <algorithm>
#include <queue>
#include <string.h>
#include <stdio.h>
using namespace std;
#define MAXINT 0x7FFFFFFF
#define Puddle 0
#define Nothing 1
#define Initial 2
#define Hole 3
#define Food 4
int dx[] = {0, 1, 0, -1};
int dy[] = {-1, 0, 1, 0};
int main()
{
int w, h;
int map[8][8];
int cost[8][8];
bool visited[8][8];
int hp[8][8];
while (cin >> w >> h && w > 0 && h > 0)
{
for (int i = 0; i < 8; i++)
for (int j = 0; j < 8; j++)
{
map[i][j] = -1;
cost[i][j] = MAXINT;
visited[i][j] = false;
hp[i][j] = 0;
}
for (int i = 0; i < h; i++)
for (int j = 0; j < w; j++)
cin >> map[i][j];
queue< pair<int, int> > q;
for (int i = 0; i < h; i++)
for (int j = 0; j < w; j++)
if (map[i][j] == Initial)
{
q.push(make_pair<int, int>(i, j));
cost[i][j] = 0;
hp[i][j] = 6;
break;
}
int time = -1;
while (!q.empty())
{
int x = q.front().first;
int y = q.front().second;
q.pop();
if (map[x][y] == Hole)
{
time = cost[x][y];
break;
}
for (int i = 0; i < 4; i++)
if (hp[x][y] > 1 &&
(x + dx[i] >= 0 && x + dx[i] < h && y + dy[i] >= 0 && y + dy[i] < w) &&
map[x + dx[i]][y + dy[i]] != Puddle &&
(hp[x][y] - 1 > hp[x + dx[i]][y + dy[i]] && visited[x + dx[i]][y + dy[i]] == false))
{
q.push(make_pair<int, int>(x + dx[i], y + dy[i]));
cost[x + dx[i]][y + dy[i]] = cost[x][y] + 1;
if (map[x + dx[i]][y + dy[i]] == Food)
{
hp[x + dx[i]][y + dy[i]] = 6;
visited[x + dx[i]][y + dy[i]] == true;
}
else
{
hp[x + dx[i]][y + dy[i]] = hp[x][y] - 1;
}
}
}
cout << time << endl;
}
}