最小生成树,要注意多余的空格(包括x,y那行)
View Code
#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cstring>
using namespace std;
#define maxn 105
#define inf 0x3f3f3f3f
struct Point
{
int x, y;
} point[maxn], q[maxn * maxn];
int n, m;
bool map[maxn][maxn];
int dist[maxn][maxn];
char st[maxn][maxn];
int tot;
int dir[4][2] =
{
{ 0, 1 },
{ 1, 0 },
{ -1, 0 },
{ 0, -1 } };
int vis[maxn];
int lowc[maxn];
int cost[maxn][maxn];
void input()
{
scanf("%d%d", &m, &n);
gets(st[0]);
for (int i = 0; i < n; i++)
gets(st[i]);
tot = 1;
for (int i = 0; i < n; i++)
for (int j = 0; j < m; j++)
{
if (st[i][j] == '#')
map[i][j] = false;
else
map[i][j] = true;
if (st[i][j] == 'S')
{
point[0].x = i;
point[0].y = j;
}
if (st[i][j] == 'A')
{
point[tot].x = i;
point[tot].y = j;
tot++;
}
}
}
bool ok(Point &a)
{
if (a.x < 0 || a.y < 0 || a.x >= n || a.y >= m)
return false;
return map[a.x][a.y] && (dist[a.x][a.y] == -1);
}
void bfs(Point &a)
{
memset(dist, -1, sizeof(dist));
int front, rear;
front = rear = 0;
q[rear++] = a;
dist[a.x][a.y] = 0;
Point temp;
while (front != rear)
{
temp = q[front++];
if (front == maxn * maxn)
front = 0;
Point b;
for (int i = 0; i < 4; i++)
{
b.x = temp.x + dir[i][0];
b.y = temp.y + dir[i][1];
if (ok(b))
{
q[rear++] = b;
if (rear == maxn * maxn)
rear = 0;
dist[b.x][b.y] = dist[temp.x][temp.y] + 1;
}
}
}
}
void make()
{
for (int i = 0; i < tot; i++)
{
bfs(point[i]);
for (int j = 0; j < tot; j++)
cost[i][j] = dist[point[j].x][point[j].y];
}
}
int prim(int n)
{
int i, j, p;
int minc, res = 0;
memset(vis, 0, sizeof(vis));
vis[0] = 1;
for (i = 1; i < n; i++)
lowc[i] = cost[0][i];
for (i = 1; i < n; i++)
{
minc = inf;
p = -1;
for (j = 0; j < n; j++)
if (0 == vis[j] && minc > lowc[j])
{
minc = lowc[j];
p = j;
}
if (inf == minc)
return -1;
res += minc;
vis[p] = 1;
for (j = 0; j < n; j++)
if (0 == vis[j] && lowc[j] > cost[p][j])
lowc[j] = cost[p][j];
}
return res;
}
int main()
{
//freopen("t.txt", "r", stdin);
int t;
scanf("%d", &t);
while (t--)
{
input();
make();
printf("%d\n", prim(tot));
}
return 0;
}