题意:给定一个迷宫,在一个迷宫内,建立一颗最小生成树连接所有点。(这些点即‘A’或‘S’)
题解:通过BFS找到'S'与每个’A'之间的最短路径。然后prim 建立最小生成树。
#include <queue>
#include <cstring>
#include <iostream>
using namespace std;
#define INF 10000000
#define N 52
bool vis[N][N];
int path[N*2][N*2], map[N][N];
int dir[4][2]={{-1,0},{0,1},{1,0},{0,-1}};
int row, col, cnt, Brog;
struct Node
{
int x, y, step;
} node[N*2];
bool isOk ( int a, int b )
{
if ( a < 0 || a > row || b < 0 || b > col || vis[a][b] == 1 || map[a][b] == -1 )
return false;
return true;
}
void bfs ()
{
Node current, next;
queue<Node> Q;
memset(path,0,sizeof(path));
for ( int i = 1; i <= Brog; i++ )
{
while ( ! Q.empty() ) Q.pop();
memset(vis,0,sizeof(vis));
node[i].step = cnt = 0;
vis[node[i].x][node[i].y] = 1;
Q.push ( node[i] );
while ( ! Q.empty () )
{
current = Q.front ();
Q.pop ();
int x = current.x;
int y = current.y;
if ( map[x][y] != 0 && map[x][y] != -1 )
{
cnt++;
path[i][map[x][y]] = path[map[x][y]][i] = current.step;
if ( cnt == Brog ) break;
}
for ( int j = 0; j < 4; j++ )
{
x = current.x + dir[j][0];
y = current.y + dir[j][1];
if ( isOk ( x, y ) )
{
next.x = x;
next.y = y;
next.step = current.step + 1;
vis[x][y] = 1;
Q.push ( next );
}
}
}
}
}
int prim()
{
int i, j, k, min, sum = 0;
int dis[102], mark[102] = { 0 };
for ( i = 1; i <= Brog; i++ )
dis[i] = INF;
dis[1] = 0;
for ( i = 1; i <= Brog; i++ )
{
min = INF;
for ( j = 1; j <= Brog; j++ )
{
if ( ! mark[j] && dis[j] < min )
{
k = j;
min = dis[j];
}
}
sum += min;
mark[k] = 1;
for ( j = 1; j <= Brog; j++ )
{
if ( ! mark[j] && path[k][j] < dis[j] )
dis[j] = path[k][j];
}
}
return sum;
}
int main()
{
int t;
char str[52];
cin >> t;
while ( t-- )
{
cin >> col >> row;
cin.getline (str,52); /* 输入需要注意 */
Brog = 0;
memset(node,0,sizeof(node));
for ( int i = 0; i < row; i++ )
{
cin.getline(str, 52, '\n');
for ( int j = 0; j < col; j++ )
{
if ( str[j] == 'A' || str[j] == 'S' )
{
Brog++;
map[i][j] = Brog;
node[Brog].x = i;
node[Brog].y = j;
}
else if ( str[j] == ' ' )
map[i][j] = 0;
else if ( str[j] == '#' )
map[i][j] = -1;
}
}
bfs();
cout << prim() << endl;
}
return 0;
}