HDU 1242 Rescue BFS+优先队列

Problem Description

Angel was caught by the MOLIGPY! He was put in prison by Moligpy. The prison is described as a N * M (N, M <= 200) matrix. There are WALLs, ROADs, and GUARDs in the prison.

Angel's friends want to save Angel. Their task is: approach Angel. We assume that "approach Angel" is to get to the position where Angel stays. When there's a guard in the grid, we must kill him (or her?) to move into the grid. We assume that we moving up, down, right, left takes us 1 unit time, and killing a guard takes 1 unit time, too. And we are strong enough to kill all the guards.

You have to calculate the minimal time to approach Angel. (We can move only UP, DOWN, LEFT and RIGHT, to the neighbor grid within bound, of course.)

 

 

Input

First line contains two integers stand for N and M.

Then N lines follows, every line has M characters. "." stands for road, "a" stands for Angel, and "r" stands for each of Angel's friend.

Process to the end of the file.

 

 

Output

For each test case, your program should output a single integer, standing for the minimal time needed. If such a number does no exist, you should output a line containing "Poor ANGEL has to stay in the prison all his life."

 

 

Sample Input

7 8

#.#####.

#.a#..r.

#..#x...

..#..#.#

#...##..

.#......

........

 

 

Sample Output

13

一般的广搜问题(BFS),解决的是最短路的问题,也就是所谓用队列实现广度搜索,这条题目增设了一些士兵,一旦遇到了士兵需要多花费一分钟的时间去打败他,题目要求是要去输出最短时间,并不是最短路,实际要求的是最短时间,那么我们利用优先队列就可以来实现存在选择某一项值最优可以先出队

不同于队列,队列是以某一顺序入队,再以此顺序出队,而优先队列以某一顺序入队,出队顺序取决于优先值,这一点可以说它已不再属于真正意义上的队列了。

有一篇我转载的文章专门讲解了优先队列的使用,我就不在赘述优先队列的基本使用方法了。

总体思想上是,根据时间进行优先性选择,每次都要出队当前队列元素中记录时间最少的出队,而入队处理时,我们可以按顺序对四个方向上的各种情况按正常处理入队就行了,出队顺序由优先队列根据预设优先性自动控制。本题即以时间最少的先出队。这样,我们就可以从“a”进行基于优先队列的范围搜索了,并且在第一次抵达有朋友的位置时得到正确结果。

优先队列的定义

struct number1{  
    int x;  
    bool operator < (const number1 &a) const {  
        return x>a.x;//最小值优先  
    }  
};  
struct number2{  
    int x;  
    bool operator < (const number2 &a) const {  
        return x<a.x;//最大值优先  
    }  
};  

代码如下:

#include<iostream>
#include<cstdio>
#include<cstring>
#include<queue>
#define MAXN 205
using namespace std;
typedef struct p
{
    int x,y,t;
    bool operator < (const p &a) const
    {
        return t>a.t;//取时间最少优先
    }
}point;
char matrix[MAXN][MAXN];
point start,next,s;//point类型
int n,m;
int dir[4][2]={0,1,0,-1,1,0,-1,0};//定义四个方向
int bfs()
{
    int xx,yy,i;
    priority_queue<point>q;//优先队列
    q.push(start);
    while(!q.empty())//当队列元素非空
    {
        next=q.top();
        s=next;
        q.pop();//取出优先队列队头
        for(i=0;i<4;i++)//对四个方向进行广搜
        {
            xx=s.x+dir[i][0];
            yy=s.y+dir[i][1];
            if(xx<1||xx>n||yy<1||yy>m||matrix[xx][yy]=='#')
                continue;
            if(matrix[xx][yy]=='r')//找到朋友返回最终结果
                return next.t+1;
            if(matrix[xx][yy]=='.')
            {
                next.x=s.x+dir[i][0];
                next.y=s.y+dir[i][1];
                next.t=s.t+1;
                q.push(next);
                matrix[xx][yy]='#';//将已走过的路赋为'#'标识为不可走,省去了visited[MAXN][MAXN]
                continue;
            }
            if(matrix[xx][yy]=='x')
            {
                next.x=s.x+dir[i][0];
                next.y=s.y+dir[i][1];
                next.t=s.t+2;//遇到士兵时间加2
                q.push(next);
                matrix[xx][yy]='#';
                continue;
            }
        }
    }
    return -1;
}
int main()
{
    int i,j,k;
    while(cin>>n>>m)
    {
        for(i=1;i<=n;i++)
        {
            scanf("%s",matrix[i]+1);
        }
        for(i=1;i<=n;i++)
            for(j=1;j<=m;j++)
        {
            if(matrix[i][j]=='a')
            {
                start.x=i;
                start.y=j;
                start.t=0;
                break;
            }
        }
        k=bfs();
        if(k==-1)
            cout<<"Poor ANGEL has to stay in the prison all his life." <<endl;
        else
            cout<<k<<endl;
    }
    return 0;
}

 

posted @ 2015-02-21 18:46  fancy_boy  阅读(164)  评论(0编辑  收藏  举报