题意:在一个y行 x列的迷宫中,有可行走的通路空格’ ‘,不可行走的墙’#’,还有两种英文字母A和S,现在从S出发,要求用最短的路径L连接所有字母,输出这条路径L的总长度
最小生成树
#include <cstdio>
#include <cstring>
#include <iostream>
#include <queue>
#include <algorithm>
#include <vector>
#include <utility>
#define rep(i, j, k) for(int i = j; i <= k; i++)
using namespace std;
int n, m, dist[109][109], vis[109][109], cnt, mp[109][109], father[109], ans;
char a[109][109];
int ax [] = {0, 0, 0, 1, -1}, ay[] = {0, 1, -1, 0, 0};
vector < pair <int, pair <int, int> > > edge;
void bfs (int x, int y)
{
queue <pair <int, int> > q;
memset (vis, -1, sizeof (vis));
vis[x][y] = 0;
q.push (make_pair (x, y));
while (!q.empty ())
{
pair<int, int> now = q.front ();
q.pop ();
int px = now.first, py = now.second ;
if (mp[px][py])
dist[ mp[x][y] ][ mp[px][py] ] = vis[px][py];
rep (i, 1, 4)
{
int dx = px + ax[i], dy = py + ay[i];
if (dx < 1 || dx > n || dy < 1 || dy > m || vis[dx][dy] != -1 || a[dx][dy] == '#')
continue;
vis[dx][dy] = vis[px][py] + 1;
q.push (make_pair (dx, dy));
}
}
return;
}
int get_father (int x)
{
if (father[x] == x)
return x;
return get_father (father[x]);
}
void work ()
{
rep (i, 1, cnt)
rep (j, 1, cnt)
if (i != j)
edge.push_back ( make_pair (dist[i][j], make_pair (i, j)));
rep (i, 1, cnt)
father[i] = i;
sort (edge.begin (), edge.end ());
int size = edge.size ();
//rep (i, 0, size - 1) printf ("%d === %d %d \n", edge[i].first, edge[i].second.first, edge[i].second.second);
rep (i, 0, size - 1)
{
//pair <int, int> now = edge[i].second;
int u = get_father (edge[i].second.first), v = get_father (edge[i].second.second);
if (u != v)
father[v] = u, ans += edge[i].first;
}
printf ("%d\n", ans);
}
int main ()
{
int ti;
cin >> ti;
while (ti--)
{
cin >> m >> n;
edge.clear ();
ans = 0;
char s0[100];
gets (s0);
rep (i, 1, n)
{
char s[100];
gets (s);
int t = strlen (s);
rep (j, 0, t - 1)
a[i][j + 1] = s[j];
}
cnt = 0;
memset (mp, 0, sizeof (mp));
rep (i, 1, n)
rep (j, 1, n)
if (a[i][j] == 'A' || a[i][j] == 'S')
mp[i][j] = ++cnt;
//for (int i = 1; i <= n; i++, printf ("\n")) rep (j, 1, m) printf ("%d", mp[i][j]);
rep (i, 1, n)
rep (j, 1, n)
if (mp[i][j])
bfs (i, j);
//rep (i, 1, cnt) rep (j, 1, cnt) printf ("%d %d ==== %d\n", i, j, dist[i][j]);
work ();
}
return 0;
}