题目大意:在一个y行 x列的迷宫中,有可行走的通路空格’ ‘,不可行走的墙’#’,还有两种英文字母A和S,现在从S出发,要求用最短的路径L连接所有字母,输出这条路径L的总长度。
Sample Input
2
6 5
#####
#A#A##
# # A#
#S ##
#####
7 7
#####
#AAA###
# A#
# S ###
# #
#AAA###
#####
Sample Output
8
11
AC Code : bfs+prim Memory:260K Time:16MS
#include <iostream>
#include <cstdio>
#include <cstring>
#include <queue>
#define Max 55
#define Inf 0x7fffffff
using namespace std;
char map[Max][Max]; //0--'#',1--' ',2--'A',-1--'S'
int dis[102][102];
//int dis[2500][2500];
int hash[Max][Max];
int dist[Max][Max];
int x,y;
int num; //记录A点的个数
int move[4][2]={{-1,0},{1,0},{0,-1},{0,1}};
void init()
{ int i,j;
char C;
char str[Max];
scanf("%d%d",&y,&x);
memset(dis,0,sizeof(dis));
memset(hash,0,sizeof(hash));
num=0;
for(i=1;i<=x;i++)
map[i][0]=map[i][y+1]='#';
for(j=0;j<=y+1;j++)
map[0][j]=map[x+1][j]='#';
for(i=1;i<=x;i++)
{
gets(str);
for(j=1;j<=y;j++)
{ C=getchar();
if(C=='S'||C=='A') {
num++;
hash[i][j]=num;
}
map[i][j]=C;
}
}
}
int que_a[2501];
int que_b[2501];
void bfs(int a,int b)
{ int i;
int a1,b1;
int a2,b2;
int head,tail;
head=0,tail=0;
memset(dist,0,sizeof(dist));
que_a[tail]=a;
que_b[tail++]=b;
int s1=hash[a][b]; //源点index
int s2;
while(head<tail)
{ a1=que_a[head];
b1=que_b[head++];
if(hash[a1][b1])
{ s2=hash[a1][b1]; //现在求的点的index
dis[s1][s2]=dis[s2][s1]=dist[a1][b1];
}
for(i=0;i<4;i++)
{ a2=a1+move[i][0];
b2=b1+move[i][1];
if(a2==a&&b2==b)
continue;
if(map[a2][b2]=='#'||dist[a2][b2])
continue;
dis[hash[a1][b1]][hash[a2][b2]]=1;
dis[hash[a2][b2]][hash[a1][b1]]=1;
dist[a2][b2]=dist[a1][b1]+1;
que_a[tail]=a2;
que_b[tail++]=b2;
}
}
return;
}
int value;
void prim()
{ bool p[Max*Max];
int dist2[Max*Max];
int s,k,index,min;
value=0,k=0,s=1;
memset(p,0,sizeof(p));
for(int i=0;i<=num+1;i++)
dist2[i]=Inf;
//默认先将1号点放入最小生成树
while(1)
{ p[s]=1;
k++;
if(k==num)
break;
min=Inf,index=0;
for(int i=2;i<=num;i++)
{ if(p[i])
continue;
if(dist2[i]>dis[s][i])
dist2[i]=dis[s][i];
if(dist2[i]<min)
{
min=dist2[i];
index=i;
}
}
value+=min;
s=index;
}
}
int main()
{ int test;
scanf("%d",&test);
while(test--)
{ init();
for(int i=1;i<=x;i++)
for(int j=1;j<=y;j++)
if(hash[i][j])
bfs(i,j);
prim();
rintf("%d\n",value);
}
return 0;
}