枚举’A’和’S’到其他的点建立边,用bfs搜索权值。
import java.util.Arrays;
import java.util.LinkedList;
import java.util.Queue;
import java.util.Scanner;
public class Main_POJ3026 {
static char[][] g = new char[55][55];
static int x,y,len,vcnt,u;
static boolean[][] gvis = new boolean[55][55];
static int[] dx = {1,-1,0,0};
static int[] dy = {0,0,1,-1};
static node3026[] v = new node3026[155];
static e3026[] e = new e3026[100*100/2];
static int[] pre = new int[155];
static int[][] id = new int[55][55];
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
int t = sc.nextInt();
while(t-- > 0) {
len = 1;
u = 1;
x = sc.nextInt();
y = sc.nextInt();
sc.nextLine(); //吸收空行
for(int i=0;i<y;i++) {
g[i] = sc.nextLine().toCharArray();
}
for(int i=0;i<y;i++) {
for(int j=0;j<x;j++) {
if(g[i][j]=='A'||g[i][j]=='S') {
id[i][j] = u++; //记录顶点编号
}
}
}
for(int i=0;i<y;i++) {
for(int j=0;j<x;j++) {
if(g[i][j]=='A'||g[i][j]=='S') {
bfs(i,j);
for(int k=1;k<vcnt;k++) {
e[len++] = new e3026(id[i][j],id[v[k].x][v[k].y],v[k].step);
}
}
}
}
Arrays.sort(e,1,len);
int ans = 0;
for(int i=1;i<u;i++) {
pre[i] = i;
}
for(int i=1;i<len;i++) {
int fu = find(e[i].u);
int fv = find(e[i].v);
if(fu!=fv) {
ans += e[i].w;
pre[fu] = fv;
}
}
System.out.println(ans);
}
}
public static int find(int x) {
if(x==pre[x]) return x;
pre[x] = find(pre[x]);
return pre[x];
}
public static void bfs(int Y,int X) { //每次都是从本行往下搜索 避免与上重复
for(int i=Y;i<y;i++) {
Arrays.fill(gvis[i], false);
}
for(int i=0;i<X;i++) { //同一行的搜索过标记
if(g[Y][i]=='A'||g[Y][i]=='S')
gvis[Y][i] = true;
}
Queue<node3026> q = new LinkedList<node3026>();
q.offer(new node3026(Y,X,0));
gvis[Y][X] = true;
vcnt = 1;
while(!q.isEmpty()) {
node3026 temp = q.poll();
for(int i=0;i<4;i++) {
int xi = dx[i]+temp.x;
int yi = dy[i]+temp.y;
if(xi>=0&&xi<x&&yi>0&&yi<=y&&!gvis[xi][yi]&&g[xi][yi]!='#') {
q.offer(new node3026(xi,yi,temp.step+1));
gvis[xi][yi] = true;
if(g[xi][yi]=='A'||g[xi][yi]=='S') {
v[vcnt++] = new node3026(xi,yi,temp.step+1);
}
}
}
}
}
}
class node3026{
int x,y,step;
public node3026(int x,int y,int step) {
this.x = x;
this.y = y;
this.step = step;
}
}
class e3026 implements Comparable<e3026> {
int u,v,w;
public e3026(int u,int v,int w) {
this.u = u;
this.v = v;
this.w = w;
}
@Override
public int compareTo(e3026 o) {
return this.w-o.w;
}
}