道题比较坑,就是输入N,M之后可能有多个空格这里要注意;
方法:1:建图,把A进行编号在存储到图中;
2:利用BFS找出任意两点的最短距离;
3:利用kruscal生成最小生成树;
#include<iostream> #include<cstdio> #include<cstdlib> #include<algorithm> #include<cmath> #include<queue> #include<cstring> #include<vector> using namespace std; int d[4][2] = { 0,1,1,0,0,-1,-1,0 }; class Node { public: int x,y,step; }q[100024]; class node { public: int x,y; }e[124]; Node kru[20024]; int set[124]; bool cmp( Node a ,Node b ) { return a.step < b.step; } int find( int x ) { return set[x] == x ? x : set[x] = find( set[x] ); } int Kruscal( int N ) { int ans=0,X,Y; for( int i = 0 ; i < N ; i++ ) { if( ( X = find( kru[i].x ) )!=( Y = find(kru[i].y) ) ) { ans += kru[i].step; set[Y] =X; } } return ans; } int BFS( int x,int y , int end ,int map[][54]) { int S=0,E=0; bool hash[54][54] = {0}; hash[x][y] = true;; q[S].x = x ;q[S].y = y; q[S++].step = 0; while( E < S ) { Node p = q[E]; for( int i = 0 ; i < 4 ; i ++ ) { int dx = d[i][0] + p.x ,dy = d[i][1] + p.y; if( !hash[dx][dy] && map[dx][dy] != -1 ) { if( map[dx][dy]==end ) return p.step + 1; q[S].x = dx , q[S].y = dy; q[S++].step = p.step + 1; hash[dx][dy] = true; } } E++; } return 0x7fffffff; } int main( ) { int map[54][54],Case,N,M; char str[54],c; while( scanf( "%d",&Case )==1 ) { while( Case-- ) { scanf( "%d %d",&N,&M ); int count = 2,cnt=0; for( int i = 0 ; i <54 ; i++ ) { for( int j = 0 ; j < 54 ; j ++ ) map[i][j] = -1; } while( c = getchar( ),c!='\n' ); for( int i = 1 ; i <= M ; i ++ )//建图 { gets(str); for( int j = 0 ; j < N ; j ++ ) { if( str[j] =='#' ) map[i][j+1] = -1; else if( str[j] ==' ' ) map[i][j+1] = 0; else if( str[j] =='S' ) { map[i][j+1] = 1;e[1].x = i ;e[1].y = j+1; } else { e[count].x = i ;e[count].y = j+1; map[i][j+1] = count++; } } } for( int i = 1 ; i < count ; i ++ )//搜索出i点到任意点的最短距离 { set[i] = i; for( int j = i + 1 ; j < count ; j ++ ) { kru[cnt].x = i;kru[cnt].y = j; kru[cnt++].step = BFS( e[i].x ,e[i].y , j ,map); } } sort( kru ,kru + cnt , cmp ); printf( "%d\n",Kruscal( cnt ) ); } } //system( "pause" ); return 0; }