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的时间拆掉
全地图被不能拆的墙(也就是"#")包围,只有一个出口。
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); } }