思路:先BFS求出S到各点A的最短距离,建图然后套模板
#include <cstdio>
#include <queue>
#include <cstring>
#include <iostream>
#include <cstdlib>
#include <algorithm>
#include <vector>
#include <string>
#include <set>
#include <ctime>
#include <cmath>
#include <cctype>
using namespace std;
#define maxn 100000
#define LL long long
int cas=1,T;
typedef struct node
{
int x,y;
}point;
int dir[4][2]={{0,-1},{-1,0},{1,0},{0,1}};
int n,m,num;
char maze[55][55];
int pos[55][55]; //记录A和S坐标的标号
int mapp[105][105]; //建图
int dis[105][105]; //记录步数
void bfs(int x,int y)
{
int vis[55][55];
memset(vis,0,sizeof(vis));
memset(dis,0,sizeof(dis));
queue<point>q;
point p,cnt,temp;
p.x=x;
p.y=y;
vis[p.x][p.y]=1;
q.push(p);
while (!q.empty())
{
cnt = q.front();q.pop();
if (pos[cnt.x][cnt.y])
mapp[pos[x][y]][pos[cnt.x][cnt.y]]=dis[cnt.x][cnt.y];
for (int i = 0;i<4;i++)
{
int cx = cnt.x+dir[i][0];
int cy = cnt.y+dir[i][1];
if (cx<=m&&cx>=1&&cy<=n&&cy>=1 && !vis[cx][cy]&&maze[cx][cy]!='#')
{
vis[cx][cy]=1;
temp.x=cx;
temp.y=cy;
q.push(temp);
dis[cx][cy]=dis[cnt.x][cnt.y]+1;
}
}
}
}
int Prim()
{
int w[105];
int sum = 0;
int vis[105];
for (int i = 1;i<=num;i++)
{
w[i]=mapp[1][i];
vis[i]=0;
}
vis[1]=1;
for (int i = 1;i<=num;i++)
{
int temp= 2550;
int u = 1;
for (int j = 1;j<=num;j++)
if (!vis[j] && temp > w[j])
{
temp = w[j];
u=j;
}
vis[u]=1;
sum+=w[u];
for (int j = 1;j<=num;j++)
if (!vis[j] && w[j]>mapp[u][j])
w[j]=mapp[u][j];
}
return sum;
}
void graph()
{
for (int i = 1;i<=num;i++)
for (int j = 1;j<=num;j++)
mapp[i][j]=2550;
for (int i = 1;i<=n;i++)
for (int j = 1;j<=m;j++)
if (pos[i][j])
bfs(i,j);
}
int main()
{
//freopen("in","r",stdin);
scanf("%d",&T);
while (T--)
{
memset(pos,0,sizeof(pos));
num=0;
scanf("%d%d",&m,&n);
char a[5];
gets(a);
for (int i = 1;i<=n;i++)
{
gets(maze[i]);
for (int j = 1;j<=m;j++)
if (maze[i][j]=='A' || maze[i][j]=='S')
pos[i][j]=++num;
}
graph();
printf("%d\n",Prim());
}
//printf("time=%.3lf",(double)clock()/CLOCKS_PER_SEC);
return 0;
}