13
解析:
广搜必须都是1个时间才能搜,才能保证这个BFS树是等距离向外伸展的,而这个不是等距离的,所以需要一些处理。
1、我的方法是,找到天使后,把时间比下大小,最后输出最小的。需要优化,只这么做的话,会TLE的,如果走过一个格子,这个格子存走过时候的时间,下次再走到这个格子,如果时间比格子里的短,就入队,否则,就不用入队了。20MS。
2. 优先队列+BFS 因为等距离的BFS的话,队列里的time值是从小往大排的,那直接用优先队列就可以了丫 0MS
/****ZOJ 1649****/ #include <iostream> #include <cstdio> #include <cstring> #include <cstdlib> #include <set> #include <queue> #include <algorithm> #define MAXN 210 #define INF 1000000 //不要太大,太大结果错误 #define RST(N)memset(N, 0, sizeof(N)) using namespace std; struct { int x, y; int step; int time; }q[1000000]; char Map[MAXN][MAXN]; //地图 int Min[MAXN][MAXN]; //走到每个位置所需的最小时间 int front, rear, res; int n, m, Sx, Sy, Ex, Ey; const int dx[] = {-1, 0, 1, 0}; //方向数组 const int dy[] = {0, 1, 0, -1}; bool check(int x, int y) //走下一步的条件 { return x>=0 && y>=0 && x<n && y<m && Map[x][y]!='#'; } void Init() { front = rear = 0; memset(Min, INF, sizeof(Min)); //初始化Min Min[Sx][Sy] = 0; q[rear].x = Sx, q[rear].y = Sy; q[rear].time = 0, q[rear++].step = 0; //将起始position加入队列 } int main(int argc, char *argv[]) { while(~scanf("%d %d", &n, &m)) { for(int i=0; i<n; i++) { scanf("%s", Map[i]); for(int j=0; Map[i][j]; j++) { if(Map[i][j] == 'a') { Ex=i, Ey=j; } //记录终点position else if(Map[i][j] == 'r') { Sx=i, Sy=j; } //记录起始position } } Init(); //个别数据初始化 while(front < rear) { //当队列不为空 int px = q[front].x; int py = q[front].y; //current position for(int i=0; i<4; i++) { int xx = px + dx[i]; int yy = py + dy[i]; //printf("xx = %d yy = %d\n", xx, yy); if(check(xx, yy)) { //printf("Matched xx = %d, yy = %d\n", xx, yy); //v[xx][yy] = 1; int qt = q[front].time + 1; if(Map[xx][yy] == 'x') qt++; //如果是警卫,杀死,时间+1 if(qt < Min[xx][yy]) { //如果这种走法比之前走到该位置所花的时间少,则加入队列,否则不用加入队列 Min[xx][yy] = qt; q[rear].x = xx, q[rear].y = yy; q[rear].step = q[front].step + 1; q[rear++].time = qt; } //printf("Matched cur_char = %c\n", Map[px][py]); //printf("Matched next_pos_char = %c\n", Map[xx][yy]); //printf("Matched cur_step = %d, cur_time = %d\n", q[front].step, q[front].time); //printf("Matched step = %d, time = %d\n", q[rear].step, q[rear].time); } } front++; } if(Min[Ex][Ey] < INF) printf("%d\n", Min[Ex][Ey]); else puts("Poor ANGEL has to stay in the prison all his life."); } return 0; }
#include <iostream> #include <cstdio> #include <cstring> #include <cstdlib> #include <limits.h> #include <set> #include <queue> #include <algorithm> #define MAXN 210 #define RST(N)memset(N, 0, sizeof(N)) using namespace std; typedef struct Node { int x, y; int time; }Node; Node start; priority_queue <Node> pq; char Map[MAXN][MAXN]; int v[MAXN][MAXN], n, m, res; const int dx[] = {-1, 0, 1, 0}; const int dy[] = {0, 1, 0, -1}; bool operator < (Node a, Node b) { return a.time > b.time; } bool check(int x, int y) { return x>=0 && y>=0 && x<n && y<m && Map[x][y]!='#' &&!v[x][y]; } int BFS() { Node cur; int xx, yy, px, py, T; while(!pq.empty()) { cur = pq.top(), pq.pop(); px = cur.x, py = cur.y, T = cur.time; for(int i=0; i<4; i++) { xx = px + dx[i], yy = py + dy[i]; if(check(xx, yy)) { v[xx][yy] = 1; if(Map[xx][yy] == 'a') return T+1; //基友见面,返回 cur.x = xx, cur.y = yy, cur.time = T+1; if(Map[xx][yy] == 'x') cur.time++; //打死警卫,时间+1 pq.push(cur); //入队 } } } return -1; } int main(int argc, char *argv[]) { while(~scanf("%d %d", &n, &m)) { RST(v); while(!pq.empty()) pq.pop(); //清空队列 for(int i=0; i<n; i++) { scanf("%s", Map[i]); for(int j=0; j<m; j++) { if(Map[i][j] == 'r') { //记录初始position start.x = i, start.y = j; start.time = 0; pq.push(start); //入队 v[i][j] = 1; } } } res = BFS(); if(res != -1) printf("%d\n", res); else puts("Poor ANGEL has to stay in the prison all his life."); } return 0; }
ZOJ 1649 && HDU 1242 Rescue (BFS + 优先队列)
原文:http://blog.csdn.net/keshacookie/article/details/44034839