题干:

小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

Hint

解题报告:

     优先队列搞一波pq,如果是普通的bfs,那么队列即可,因为队列就能保证取出来的Node结构体的t是最小值,但是这题不一样,所以需要pq。刚开始写的时候wa了好几发最后发现是main函数中那个双层循环的内层循环写成了for(int j=i; j<=m; j++)、、、我也是醉了好像不止第一次错在这里了、、、

AC代码:

#include<cstdio>
#include<queue>
#include<cstring>
#include<cmath>
#include<map>
#include<iostream>
#include<algorithm>
#define ll long long
using namespace std;
struct Node {
int x,y;
int t;
Node(){}
Node(int x,int y,int t):x(x),y(y),t(t){}
bool operator<(const Node b) const{
return t > b.t;
}
};
int n,m;
int nx[4]={0,1,0,-1};
int ny[4]={1,0,-1,0};
bool vis[205][205];
char maze[205][205];
int bfs(int sx,int sy) {
priority_queue<Node> pq;
pq.push(Node(sx,sy,0));
Node cur;
int tx,ty;
while(pq.size()) {
cur=pq.top();pq.pop();

for(int k = 0; k<4; k++) {
tx = cur.x + nx[k];
ty = cur.y + ny[k];
if(maze[tx][ty] == '#' || vis[tx][ty] || tx < 1 || tx > n || ty < 1 || ty > m) continue;
vis[tx][ty]=1;
if(maze[tx][ty] == 'W') return cur.t + 1;
else if(maze[tx][ty] == '.') pq.push(Node(tx,ty,cur.t+1));
else pq.push(Node(tx,ty,cur.t + 1 + maze[tx][ty] - '0'));
}

}
return -1;

}
int main()
{
int t,sx,sy;
cin>>t;
while(t--) {
scanf("%d%d",&n,&m);
memset(vis,0,sizeof vis);
for(int i = 1; i<=n; i++) {
scanf("%s",maze[i]+1);
}
for(int i = 1; i<=n; i++) {
for(int j = 1; j<=m; j++) {
if(maze[i][j] == 'Z') {
sx=i,sy=j;break;
}
}
}
int ans = bfs(sx,sy);
if(ans == -1) puts("IMPOSSIBLE");
else printf("%d\n",ans);

}
return 0 ;
}