营救BFS
bfs通常用来寻找从特定源节点出发的最短路径,dfs找到的解不是最优的,可能从多个源节点重复进行。
(ZOJ1649)Angel的朋友营救angel,x为警卫,须杀死警卫才能到达其方格,费时一个单位,移动一格费时一个单位,#为墙壁。问至少需要多长时间。
#include <stdio.h>
#include <stdlib.h>
#include <queue>
#include <algorithm>
#include <string.h>
#define INF 1000000
using namespace std;
//到达某个方格时的状态
struct point{
int x,y;
int step;
int time;
};
//结点队列
queue <point> Q;
int N,M;
char map[200][200]; //迷宫地图
int mintime[200][200]; //到达某结点的最短时间
int dir[4][2] = {-1,0,0,1,1,0,0,-1};
int ax,ay;
int bfs (point s) {
Q.push(s);
point hd;
while(!Q.empty()) {
//取队列头结点
hd = Q.front();
Q.pop();
for (int i = 0;i < 4;i++) {
int x = hd.x + dir[i][0];
int y = hd.y + dir[i][1];
if (x>=0&&x<N&&y>=0&&y<M&&map[x][y]!='#') {
//构造新结点
point t;
t.x = x;
t.y = y;
t.step = hd.step + 1;
t.time = hd.time + 1;
if (map[x][y] =='x')
t.time++;
//若到达该结点所花时间更少,入队列
if (t.time < mintime[x][y]) {
mintime[x][y] = t.time;
Q.push(t);
}
}
}
}
//返回到达angel的最短时间
return mintime[ax][ay];
}
int main () {
while (scanf("%d %d",&N,&M) != EOF) {
memset(map,0,sizeof(map));
int sx,sy;
for (int i = 0;i < N;i++)
scanf("%s",map[i]);
for (int i = 0;i < N;i++) {
for (int j = 0;j < M;j++) {
mintime[i][j] = INF;
if (map[i][j] == 'a') {
ax = i;
ay = j;
}else if (map[i][j] == 'r') {
sx = i;
sy = j;
}
}
}
point start;
start.x = sx;
start.y = sy;
start.step = 0;
start.time = 0;
mintime[sx][sy] = 0;
int mint = bfs(start);
if (mint < INF)
printf("%d\n",mint);
else printf ("Pool Angel has to stay in the prison all her life.\n");
}
return 0;
}