Borg Maze POJ - 3026 (BFS + 最小生成树)

时间:2023-03-10 04:57:19
Borg Maze POJ - 3026 (BFS + 最小生成树)

题意:

求把S和所有的A连贯起来所用的线的最短长度。。。

这道题。。不看discuss我能wa一辈子。。。

输入有坑。。。

然后,,,也没什么了。。。还有注意 一次bfs是可以求当前点到所有点最短距离的。。。

#include <iostream>
#include <cstdio>
#include <cstring>
#include <queue>
#include <algorithm>
#include <cmath>
#define mem(a, b) memset(a, b, sizeof(a))
using namespace std;
const int maxn = , INF = 0x7fffffff;
int f[maxn], d[][];
int cnt, n, m;
int dis[][] = {{,},{-,},{,},{,-}};
char str[][], temp[maxn];
struct node
{
int u, v, w;
}Node[maxn]; struct edge
{
int x, y;
}Edge[maxn]; void add(int u, int v, int w)
{
Node[cnt].u = u;
Node[cnt].v = v;
Node[cnt++].w = w;
} void init()
{
for(int i=; i<maxn; i++) f[i] = i;
cnt = ;
} int cmp(node a, node b)
{
return a.w < b.w;
} int find(int x)
{
// return f[x]==x?x:(f[x] = find(f[x]));
if(f[x] == x) return x;
int r = f[x];
while(r != f[r]) r = f[r];
int i = x, j;
while(i!=r)
{
j = f[i];
f[i] = r;
i = j;
}
return r;
} void bfs(edge s)
{
queue<edge> Q;
mem(d, );
Q.push(s);
d[s.x][s.y] = ;
while(!Q.empty())
{
s = Q.front(); Q.pop();
for(int i=; i<; i++)
{
edge t;
t.x = s.x + dis[i][];
t.y = s.y + dis[i][];
if(t.x < || t.x >= n || t.y < || t.y >= m || d[t.x][t.y] || str[t.x][t.y] == '#') continue;
d[t.x][t.y] = d[s.x][s.y] + ;
Q.push(t);
}
}
} int main()
{
int T;
scanf("%d",&T);
while(T--)
{
init();
int ans = ;
scanf("%d%d",&m,&n);
gets(temp);
// getchar();
for(int i=; i<n; i++)
{
gets(str[i]);
for(int j=; j<m; j++)
{
if(str[i][j] == 'A' || str[i][j] == 'S')
Edge[++ans].x = i, Edge[ans].y = j;
}
}
for(int i=; i<=ans; i++)
{
bfs(Edge[i]);
for(int j=i+; j<=ans; j++)
add(i, j, d[Edge[j].x][Edge[j].y] - ); }
sort(Node, Node+cnt, cmp);
int sum = ;
for(int i=; i<cnt; i++)
{
int r = find(Node[i].u);
int l = find(Node[i].v);
if(r == l) continue;
f[r] = l;
sum += Node[i].w;
} printf("%d\n",sum); } return ;
}