解题思路:
把输入原图中的‘A’和‘S’取出记录其坐标,然后在原图中用BFS求每个‘A’或‘S’到其他点的距离,便可得到每个‘A’或‘S’到其他‘A’(‘S’)的距离,因此可为这些点(‘A’或‘S’)构造一个新的邻接矩阵。对新的图用prim算法求最小生成树即可!
注意这没节操的输入!
//poj 3026
#include <iostream>
#include <cstring>
#include <cstdio>
#include <queue>
using namespace std;
const int SIZE=60;
const int INF=0x7fffffff;
typedef struct node
{
int x;
int y;
}node;
int n, m;
char str[SIZE][SIZE];
node as[2*SIZE];
int tot;
int map[2*SIZE][2*SIZE];
queue<node> Q;
int dir[4][2]={{-1,0},{0,1},{1,0},{0,-1}};
int vis[SIZE][SIZE];
bool check(node v)
{
if(v.x<0 || v.x>=n || v.y<0 || v.y>=n || vis[v.x][v.y]>=0 || str[v.x][v.y]=='#')
return false;
return true;
}
void bfs()
{
node u,v;
memset(map,0,sizeof(map));
for(int i=0;i<tot;i++)
{
for(int ii=0;ii<SIZE;ii++)
for(int jj=0;jj<SIZE;jj++)
vis[ii][jj]=-1;
Q.push(as[i]);
vis[as[i].x][as[i].y]=0;
while(!Q.empty())
{
u=Q.front(); Q.pop();
for(int j=0;j<4;j++)
{
v.x=u.x+dir[j][0]; v.y=u.y+dir[j][1];
if(!check(v)) continue;
Q.push(v);
vis[v.x][v.y]=vis[u.x][u.y]+1;
}
}
for(int j=0;j<tot;j++)
map[i][j]=vis[as[j].x][as[j].y];
}
}
void prim(int u0)
{
int nearV[2*SIZE], lowcost[2*SIZE],sum=0;
for(int i=0;i<tot;i++)
{
lowcost[i]=map[u0][i];
nearV[i]=u0;
}
nearV[u0]=-1;
for(int i=1;i<tot;i++)
{
int minV=INF, u=-1;
for(int j=0;j<tot;j++)
{
if(nearV[j]!=-1 && lowcost[j]<minV)
{
minV=lowcost[j];
u=j;
}
}
nearV[u]=-1;
sum+=minV;
for(int j=0;j<tot;j++)
{
if(nearV[j]!=-1 && lowcost[j]>map[u][j])
{
lowcost[j]=map[u][j];
nearV[j]=u;
}
}
}
cout<<sum<<endl;
}
int main()
{
int T;
char kg[100];
cin>>T;
while(T--)
{
cin>>n>>m;
gets(kg);
tot=0;
for(int i=0;i<m;i++)
{
//cin.get(); cin.get(str[i],SIZE);
gets(str[i]);
for(int j=0;j<n;j++)
if(str[i][j]=='A' || str[i][j]=='S')
{
as[tot].x=i;
as[tot++].y=j;
}
}
bfs();
prim(0);
}
return 0;
}