http://acm.hdu.edu.cn/showproblem.php?pid=1242
问题:牢房里有墙(#),警卫(x)和道路( . ),天使被关在牢房里位置为a,你的位置在r处,杀死一个警卫要一秒钟,每走一步要一秒钟,求最短时间救出天使,不能救出则输出:Poor ANGEL has to stay in the prison all his life. 求最短路径,果断广搜BFS
限制及剪枝:
1、墙不能走,不能离开牢房范围
2、杀死一个警卫要多花一秒钟
3、当前步骤大于等于最短时间时不用继续再走(剪枝)
4、每次到达天使处要更新最短时间
5、不能走重复路(算剪枝把) //这个也要说???囧。。。
AC代码:
#include<iostream> #include<cstdio> #include<queue> #include<cstring> #define MAX 999999 using namespace std; struct Node { int x,y; int time; }; char map[210][210]; int st[210][210]; int dir[4][2]={{0,1},{0,-1},{1,0},{-1,0}}; int n,m,mintime; void Bfs(Node p) { Node now,next; queue<Node> q; int i; q.push(p); while(!q.empty()) { now = q.front(); q.pop(); if(now.time >= mintime) //剪枝,超过最短时间的不用再走了 { break; } if(map[now.x][now.y] == 'a') //找到天使时更新最短步骤 { if(now.time < mintime) { mintime = now.time; } } if(map[now.x][now.y] == 'x') //如果当前为门卫则多花1秒来杀死他 { now.time += 1; } st[now.x][now.y] = 2; //标记此路径已经到达 next.time = now.time + 1; //下一步的时间加一 for(i = 0; i < 4; i++) { next.x = now.x + dir[i][0]; next.y = now.y + dir[i][1]; if(map[next.x][next.y] != '#' && st[next.x][next.y] == 0) { st[next.x][next.y] = 1; //标记此路径已经入队 q.push(next); } } } return ; } int main() { int i,j; Node now; while(scanf("%d%d",&n,&m)!=EOF) { memset(map,'#',sizeof(map)); //初始化全为墙 memset(st,0,sizeof(st)); //初始化所有路径均未走过 mintime = MAX; for(i = 1; i <= n; i++) { for(j = 1; j <= m; j++) { cin >> map[i][j]; if(map[i][j] == 'r') { now.x = i; now.y = j; now.time = 0; } } } Bfs(now); if(mintime == MAX) { printf("Poor ANGEL has to stay in the prison all his life. "); } else { printf("%d ",mintime); } } return 0; }