题目链接:http://poj.org/problem?id=3026
本题可以把S与A视为一样的点,因为根据最小生成树的性质,起点在哪都一样。然后每一点到其余点的距离用BFS搜索得到,在搜索过程中将距离用矩阵的形式存储起来。然后在得到所有距离后,用prim算法将最小生成树求出。
代码如下:
#include <iostream> #include <stdio.h> #include <string.h> #include <stdlib.h> #include <math.h> #include <ctype.h> #include<algorithm> using namespace std; int n, m, a[60][60], map[110][110], d[110], vis1[110][110], vis[110], maxint=100000, num; char st[60][60]; int jx[]={0,0,1,-1}; int jy[]={1,-1,0,0}; struct node { int x, y, ans; }fei[10000000]; void bfs(int x, int y, int q) { int i, j, s=0, e=0, xx=0; node f1, f2; f1.x=x; f1.y=y; f1.ans=0; fei[s++]=f1; vis1[x][y]=1; while(s>e) { f1=fei[e++]; if(a[f1.x][f1.y]!=0&&a[f1.x][f1.y]!=q) { map[q][a[f1.x][f1.y]]=map[a[f1.x][f1.y]][q]=f1.ans; xx++; if(xx==num-1) { return ; } } for(i=0;i<4;i++) { f2.x=f1.x+jx[i]; f2.y=f1.y+jy[i]; if(f2.x>=0&&f2.x<n&&f2.y>=0&&f2.y<m&&!vis1[f2.x][f2.y]&&(st[f1.x][f1.y]=='A'||st[f1.x][f1.y]=='S'||st[f1.x][f1.y]==' ')) { vis1[f2.x][f2.y]=1; f2.ans=f1.ans+1; fei[s++]=f2; } } } return ; } void prim() { int ans=0, i, j, pos, min1; for(i=2;i<=num;i++) { d[i]=map[1][i]; } vis[1]=1; for(i=1;i<num;i++) { min1=maxint; for(j=2;j<=num;j++) { if(!vis[j]&&min1>d[j]) { min1=d[j]; pos=j; } } vis[pos]=1; ans+=min1; for(j=2;j<=num;j++) { if(!vis[j]&&d[j]>map[pos][j]) { d[j]=map[pos][j]; } } } printf("%d\n",ans); } int main() { int t, i, j, k, p, q; scanf("%d",&t); while(t--) { scanf("%d%d ",&m,&n); k=1; memset(a,0,sizeof(a)); memset(vis,0,sizeof(vis)); num=0; for(i=0; i<n; i++) { gets(st[i]); for(j=0; j<m; j++) { if(st[i][j]=='A'||st[i][j]=='S') { a[i][j]=k++; num++; } } } for(i=1;i<=num;i++) { for(j=1;j<=num;j++) { map[i][j]=maxint; } } for(i=0; i<n; i++) { for(j=0; j<m; j++) { if(a[i][j]) { memset(vis1,0,sizeof(vis1)); q=a[i][j]; bfs(i,j,q); } } } prim(); } return 0; }