/*
Three Kingdoms
時間: 2017/02/25
題意:劉備逃跑,從'$'逃到'!',除了'.'和'C'能走其他不能走,走'C'處要受傷害,其他字母各有攻擊範圍和傷害值,
問劉備逃跑最少扣的血或不能逃到目的地
題解:全程搜尋
先BFS搜尋每個有範圍字母能觸及到的位置儲存起來。
再從起點BFS到終點,但是注意要使用優先佇列優化這個BFS。。。
打的比較挫
*/
#include<cstdio>
#include<cstring>
#include<cmath>
#include<iostream>
#include<algorithm>
#include<queue>
#include<stack>
#include<map>
using namespace std;
#define LL long long
#define N 105
#define INF 0x3f3f3f3f
const double esp = 1e-6;
struct node
{
int x,y,vis,val;
bool operator < ( const node& a )const
{
return val > a.val;
}
};
struct point
{
int x,y,s;
};
int dx[5] = {0,0,1,-1};
int dy[5] = {1,-1,0,0};
char ma[N][N];
bool vis[N][N];
int mp[N][N][10];
int n,m;
bool pan(int x,int y)
{
if(x >= 0 && x < n && y >= 0 && y < m)
return true;
return false;
}
void BFS(int x, int y,int val,int step)
{
queue<point> p;
point now,next;
now.x = x;
now.y = y;
now.s = 0;
p.push(now);
vis[x][y] = 1;
while(!p.empty())
{
now = p.front();
p.pop();
mp[now.x][now.y][val] = 1;
for(int i = 0; i < 4; i++)
{
next.x = dx[i]+now.x;
next.y = dy[i]+now.y;
next.s = now.s+1;
if(pan(next.x,next.y) && vis[next.x][next.y] != 1 && next.s <= step)
{
p.push(next);
vis[next.x][next.y] = 1;
}
}
}
return ;
}
int ans;
int _BFS(int x, int y)
{
priority_queue<node> p;
node now,next;
now.x = x;
now.y = y;
now.vis = 0;
now.val = 0;
p.push(now);
vis[x][y] = 1;
while(!p.empty())
{
now = p.top();
if(ma[now.x][now.y] == '!')
return now.val;
p.pop();
for(int i = 0; i < 4; i++)
{
next.x = dx[i]+now.x;
next.y = dy[i]+now.y;
if(pan(next.x,next.y) && vis[next.x][next.y] != 1 && ma[next.x][next.y] != '#')
{
next.val = now.val;
next.vis = now.vis;
for(int j = 1; j <= 5; j++)
{
if(mp[next.x][next.y][j] && !(now.vis & (1 << (j-1))))
{
next.val += j;
next.vis += (1<<(j-1));
}
}
p.push(next);
vis[next.x][next.y] = 1;
}
}
}
return -1;
}
int main()
{
int T,cas = 1;
scanf("%d",&T);
while(T--)
{
scanf("%d%d",&n,&m);
memset(ma,0,sizeof(ma));
memset(mp,0,sizeof(mp));
for(int i = 0; i < n; i++)
scanf("%s",ma[i]);
int bx,by;
for(int i = 0; i < n; i++)
{
for(int j = 0; j < m; j++)
{
if(ma[i][j] == 'A')
{
ma[i][j] = '#';
memset(vis,0,sizeof(vis));
BFS(i,j,1,2);
}
else if(ma[i][j] == 'B')
{
ma[i][j] = '#';
memset(vis,0,sizeof(vis));
BFS(i,j,2,3);
}
else if(ma[i][j] == 'C')
{
ma[i][j] = '.';
mp[i][j][3] = 1;
}
else if(ma[i][j] == 'D')
{
ma[i][j] = '#';
memset(vis,0,sizeof(vis));
BFS(i,j,4,2);
}
else if(ma[i][j] == 'E')
{
ma[i][j] = '#';
memset(vis,0,sizeof(vis));
BFS(i,j,5,1);
}
else if(ma[i][j] == '$')
{
bx = i;
by = j;
}
}
}
memset(vis,0,sizeof(vis));
ans = _BFS(bx,by);
printf("Case %d: %d\n",cas++,ans);
}
return 0;
}