题干:

小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 ;
}