这道题出了几个问题:
1.数组开的太小.prim里的dis,vis数组要开的大一点,最开始只开了100,疯狂wa, 后来发现A点数有可能大于100.
2.bfs忘记判边界.一直死循环.
3.加入队列之后标记变量忘记.真弱智
4.head,tail,count忘记++就不说了.
5.这里字符的读入有点坑,要用一个gets()把行末的回车去掉,并且读入的时候必须用gets,不然空格无法读入
这道题不会做充分体现了只会做模板题的特点.根本想不到先用bfs求出距离再求MST.
#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
char map[100][100];
int dis[109];
int m,n;
int node[200][200];
int xx[4]={0,1,0,-1};
int yy[4]={1,0,-1,0};
int mmp[200][200];
struct P{
int x;
int y;
int w;
}que[4510];
void bfs(int p ,int q)
{
bool vis[200][200];
memset(vis,false,sizeof(vis));
int head = 0, tail = 1;
que[head].x = p;
que[head].y = q;
que[head].w = 0;
vis[p][q] = true;
while(head < tail)
{
int l = que[head].x;
int r = que[head].y;
if (node[l][r])
mmp[node[p][q]][node[l][r]] = mmp[node[l][r]][node[p][q]] =que[head].w;
for(int i = 0;i < 4;i ++)
{
int mx = l+xx[i];
int my = r+yy[i];
if(mx>=1 && mx <= n && my >=1 && my <= m)
if(!vis[mx][my] && map[mx][my] != '#')
{
que[tail].x = mx;
que[tail].y = my;
que[tail].w = que[head].w+1;
tail++;
vis[mx][my] = true;
}
}
head++;
}
}
int prim(int nn){
int count = 1;
int sum = 0;
for(int i = 1;i <= nn;i++)
dis[i] = mmp[1][i];
dis[1] = 0;
bool vis[200];
memset(vis,false,sizeof(vis));
vis[1] =true;
while(count<nn)
{ int mm= 999999,t;
for(int i = 1;i <= nn;i++)
if(!vis[i] && mm > dis[i])
{
mm = dis[i];
t = i;
}
sum += mm;
vis[t] = true;
for(int i = 1;i <= nn;i++)
if(!vis[i] && dis[i]>mmp[t][i]) dis[i] = mmp[t][i];
count++;
}
return sum;
}
int main(){
int T;
cin>>T;
while(T--)
{ int num = 0;
memset(node,0,sizeof(node));
cin>>m>>n;
char cnm[100];
gets(cnm);
for(int i = 1;i <= n;i ++)
{
gets(map[i]+1);
for(int j = 1;j <= m;j ++)
if(map[i][j]=='A' || map[i][j] == 'S')
{
node[i][j]=++num;
}
}
for(int i = 1;i <= n;i ++)
for(int j = 1;j <= m;j ++)
if(node[i][j]) bfs(i,j);
int nnn = prim(num);
cout<<nnn<<endl;
}
}