FJUT 1676 QAQ和迷宫(BFS+优先队列)

QAQ和迷宫

TimeLimit: 2000/1000 MS (Java/Others)  MemoryLimit: 32768/32768 K (Java/Others)
64-bit integer IO format:%I64d
收藏题目
Problem Description
QAQ被围困在一个神奇的迷宫里,迷宫里有一些墙不能行走,但是迷宫里有一些墙已经很脆弱了,可以直接拆掉,但是拆一面墙必须花费d的时间,那么QAQ要逃离这个迷宫至少需要多少时间?
Input
输入的第一行是t表示测试数据的组数,每组格式如下
1. 第一行是三个整数 h, w (3 <= h;w <= 500), 和 d (0 <= d <= 50), 地图的高度和宽度,以及拆掉一格可以拆的墙的时间
2.然后是h行w列的地图,地图内容如下
―"S"表示出发点
―"."表示平地,走过需要花费1的时间
―"#"表示不能拆的墙,不能走
―"@"表示可以拆掉的墙,可以花费d的时间拆掉
全地图被不能拆的墙(也就是"#")包围,只有一个出口。
Output
每组测试数据输出一个整数,表示走出地图所需要的最短时间。
QAQ教你广搜进阶
一般的广搜是将可行状态加入容器Q,然后每次取出最先进入Q的状态进行扩展,然后把扩展的状态依次加入Q。
而对于每个状态的权值不同的情况下,不应该是从Q拿出最先进入的状态,而是取出当前距离开始点最近的状态进行扩展。
这样的话,每次取出的状态就是依次递增的状态了。
SampleInput
16
11
5

分析:求两点间最短时间的走法,考虑BFS,
走到'@'所需要的时间是d+1,走到'.'需要的时间是1
所以我们在用BFS的时候,进行入队操作的时候,可能用时间多的,会被先放入.
但是我们每次都应从最小的时间进行扩展,使得时间呈现递增状态
这样先取到的,时间就一定小.
所以采用优先队列,队列里储存结构体,使得每次取的都是耗时最少的

需要注意的是定义优先队列,重载运算符时,'<'表示最大值优先,而'>'
表示最小值优先.- -(一开始在这个地方弄错了,耽误了好多时间)
代码如下:
#include <cstdio>
#include <iostream>
#include <cstring>
#include <algorithm>
#include <vector>
#include <queue>
#include <vector>
#include <stack>
using namespace std;
int map1[510][510];
int dir[4][2]={1,0,-1,0,0,1,0,-1};
int sx,sy,ex,ey;
int row,col,d;
int vis[510][510];
int check(int x,int y)
{
    if(x>=0&x<row&&y>=0&&y<col&&!vis[x][y]&&map1[x][y]!='#')return 1;
    return 0;
}
struct node
{
    int x;
    int y;
    int step;
};
struct Cmp
{
    bool operator()(const node &x,const node  &y){
        return x.step>y.step;
    }
};
priority_queue<node,vector<node>,Cmp> Q;
int  bfs()
{
   node a,next;
   a.x=sx;
   a.y=sy;
   a.step=0;
   Q.push(a);
   while(!Q.empty())
   {
     a=Q.top();
    // cout<<a.step<<endl;
    //   printf("%d %d\n",a.x,a.y);
     Q.pop();
     if(a.x==ex&&a.y==ey)return a.step;
     for(int i=0;i<4;i++)
     {
         next.x=a.x+dir[i][0];
         next.y=a.y+dir[i][1];
     //   cout<<next.x<<" "<<next.y<<endl;
         if(check(next.x,next.y))
         { //cout<<next.x<<" "<<next.y<<endl;
             vis[next.x][next.y]=1;
           if(map1[next.x][next.y]=='.')
           {
             next.step=a.step+1;
             Q.push(next);
           }
           else
           {
               next.step=a.step+d+1;
               Q.push(next);
           }
         }
     }
   }
   return -1;
}
int main()
{
  int t,ans;
  scanf("%d",&t);
  while(t--)
  {
      while(!Q.empty())
        Q.pop();
      memset(vis,0,sizeof(vis));
      scanf("%d%d%d",&row,&col,&d);
      for(int i=0;i<row;i++)
        for(int j=0;j<col;j++)
      {
        scanf(" %c",&map1[i][j]);
        if(map1[i][j]=='S')
        {
         sx=i;
         sy=j;
        }
        if(i==0||i==row-1)
        {
         if(map1[i][j]!='#'){
          ex=i;
          ey=j;}
        }

           if(j==0||j==col-1)
        {
         if(map1[i][j]!='#'){
          ex=i;
          ey=j;}
        }
      }
      vis[sx][sy]=1;
       ans=bfs()+1;
       printf("%d\n",ans);
  }
}

 



posted @ 2017-08-30 17:18  hinata_hajime  阅读(258)  评论(0编辑  收藏  举报