优先队列问题(此题来源哈尔滨理工大学VJ)

---恢复内容开始---

Description

小z身处在一个迷宫中,小z每分钟可以走到上下左右四个方向的相邻格之一。迷宫中有一些墙和障碍物。
同时迷宫中也有一些怪兽,当小z碰到任意一个怪兽时,小z需要将怪兽消灭掉才可以离开此方格。但消灭
怪兽会花费一定的时间。现在小z想知道走出迷宫需要花费的最少时间。

Input

输入第一行为组数T(T<=10)。

对于每组数据第一行为两个整数R和C(1<=R,C<=200)。以下R行每行有C个字符,即迷宫地图。

其中"#"代表墙和障碍物,"."表示空地,[1~9]的数字代表此处有怪兽以及消灭此处的怪兽需要的时间.

"Z"表示小z的起始位置,"W"表示迷宫出口。

对于每组数据保证起始位置和迷宫出口唯一。

Output

对于每组数据,输出走出迷宫的最短时间(单位:分钟)。如果无法走出迷宫则输出"IMPOSSIBLE"。

Sample Input

2
3 4
.Z..
.234
#.W.
4 4
Z.1.
.32.
##4.
W#..

Sample Output

5
IMPOSSIBLE
仅用普通的搜索会WA掉,此题是我遇到的第一个区分时间优先和路径优先的题,以前的问题大体上是寻找最短路径,计算走最短路径需要的时间;
这道题特点是既有路径,又有时间,并且他俩又互相影响,这时我们便要考虑优先级的问题,根据题一可知:时间优先,所以我们需要使用优先队列
这里简单介绍一下优先队列的使用
优先队列要引用头文件<queue>
定义为priority_queue<类型>名称;
用法和队列一样,优先级要用重载来完成一种是重载'<'来完成,需要在结构体内来重载,这里在一个结构体内演示一下
struct into
{
 string name;
  double score;
  bool operator < (const into &a) const
 {
  return a.score<score;
 )
};
还可以类似sort定义重载优先级需要使用头文件<vector>,同样举例说明
priority_queue<int,vector<int>,mycomper>pq;//引用方法;
struct mycomper
{
  bool operator () (const int &a,const int &b)
  {
   return a>b;
  }
};
如果会了优先队列,那么这道题就变得简单多了我附代码:
#include<iostream>
#include<string.h>
#include<queue>
#include<ctype.h>
#include<vector>
using namespace std;
int m,n;
char maps[201][201];
int vis[201][201];
int dirx[4]= {1,-1,0,0};
int diry[4]= {0,0,1,-1};
struct point
{
    int x;
    int y;
    int step;
    bool operator <(const point &a) const
    {
        return a.step<step;
    }
};
int bfs(struct point start)
{
    memset(vis,0,sizeof(vis));
    priority_queue<point>que;
    que.push(start);
    vis[start.x][start.y]=1;
    point temp,cur;
    while(!que.empty())
    {
        temp=que.top();
        que.pop();
        if(maps[temp.x][temp.y]=='W')
        {
            return temp.step;
        }
        for(int i=0; i<4; i++)
        {
            cur.x=temp.x+dirx[i];
            cur.y=temp.y+diry[i];
            if(cur.x>=0&&cur.x<m&&cur.y>=0&&cur.y<n&&maps[cur.x][cur.y]!='#'&&vis[cur.x][cur.y]==0)
            {
                if((maps[cur.x][cur.y])>='0'&&maps[cur.x][cur.y]<='9')
                {
                    int cun=maps[cur.x][cur.y]-'0'+1;
                    cur.step=temp.step+cun;
                    vis[cur.x][cur.y]=1;
                    que.push(cur);

                }
                else
                {
                    cur.step=temp.step+1;
                    vis[cur.x][cur.y]=1;
                    que.push(cur);

                }
                //cout<<cur.step<<maps[cur.x][cur.y]<<endl;

            }
        }
    }
    return -1;
}

int main()
{
    int T;
    cin>>T;
    while(T--)
    {
        cin>>m>>n;
        point start;
        for(int i=0; i<m; i++)
        {
            for(int j=0; j<n; j++)
            {
                cin>>maps[i][j];
                if(maps[i][j]=='Z')
                {
                    start.x=i;
                    start.y=j;
                    start.step=0;
                }
            }
        }
        int ans=bfs(start);
        if(ans==-1) cout<<"IMPOSSIBLE"<<endl;

        else cout<<ans<<endl;
    }
}
  

---恢复内容结束---

原文地址:https://www.cnblogs.com/VectorLin/p/5138285.html