2012年10月1日星期一

zoj 1649 Rescue_BFS

zoj 1649 Rescue_BFS

题意:

在N*M的图中,找出'r'到'a'的最少时间。其中每走一步需要花费一个时间单位,遇到守卫('x'),需要花费额外的一个时间单位来通过它。

思路:

BFS+优先队列(递增)来求解,代码写法和普通的A到B点求最短步数相同。

AC代码:10ms,C++

View Code
#include<cstdio>               // BFS + 优先队列,求少时间#include<cstring>               // 遇到哨兵多花费一秒#include<queue>#include<algorithm>using namespace std;const int MAXN = 205;int dir[4][2] = { {1,0}, {-1,0}, {0,1}, {0,-1} };char Graph[MAXN][MAXN];int vis[MAXN][MAXN];         // 用来标记一走位置struct pos{    int x, y, step;    bool operator<( pos t )const{     //优先队列递增排列        return t.step < step;    }    bool operator ==( pos t ){        return t.x == x && t.y == y;    }}S, T;priority_queue< pos >Q;int row, col;void init(){    while( !Q.empty() )Q.pop();    memset( vis, 0, sizeof(vis) );    vis[S.x][S.y] = 1;}int BFS(){    init();    pos s, t;    int i;    Q.push( S );    while( !Q.empty() )    {        s = Q.top();    Q.pop();        if( s == T )return s.step;        for( i = 0; i < 4; i++ )        {            t.x = s.x + dir[i][0];            t.y = s.y + dir[i][1];            if( t.x >=0 && t.x < row && t.y >= 0 && t.y < col && Graph[t.x][t.y] != '#' && !vis[t.x][t.y] )            {                if( Graph[t.x][t.y] == 'x' )                        t.step = s.step + 2;                else                    t.step = s.step + 1;                Q.push( t );                vis[t.x][t.y] = 1;            }        }    }    return -1;}int main(){    int i, j;    while( ~scanf( "%d%d", &row, &col ) )    {        for( i = 0; i < row; i++ )        {            scanf( "%s", Graph[i] );            for( j = 0; j < col; j++ )                if( Graph[i][j] == 'a' )                    S.x = i, S.y = j, S.step = 0;                else if( Graph[i][j] == 'r' )                    T.x = i, T.y = j;        }        int step = BFS();        if( step == -1 )printf( "Poor ANGEL has to stay in the prison all his life.\n");        else printf( "%d\n", step );    }    return 0;}/*测试数据:7 8#.#####.#a.#xr..#.x#xx....xxxx.##........#..............7 8#.#####.#.a#..r.#..#x.....#..#.##...##...#..............*/

这题使用优先代码可以很大程度上的减少代码复杂度。
这题也可以逆向搜索,从'a'到'r'。结果一样,如果遇到多起点,唯一终点的情况下,可以使用逆向搜索的方法。


TAG: