其实做完这道题整个人都不好了,感觉自己的BFS写得还好,应该不会错。结果WA了2次,看Disscus发现可能数组要开大点,结果还是WA。
然后看小优的博客,发现她也说道空格的事情,我的VS2013支持gets_s(),所以就把getchar()改成gets_s(temp),于是AC乎。
//poj3026 分小组搜索外星人,在起点或者搜到一个外星人就可以发生分组
//其实还是一个MST问题 只是现在获取节点距离要难得多。
//好难。。。 感觉首先要BFS,再prime
#include <iostream>
#include <algorithm>
#include <string>
#include <cstdio>
#define inf 10000005
using namespace std;
struct point{
int x;
int y;
};
string a[355];
int alien[355][2];
int dist[355];
bool mark[355];
int weight[355][355];
int sum = 0;
int w, h;
bool tempMark[355][355];
point queue1[62500005];
int step[355][355];
int head = 0;
int tail = 0;
int BFS(int p, int q)
{
for (int i = 0; i < w; i++)
{
for (int j = 0; j < h; j++)
step[i][j] = inf;
}
memset(tempMark, 0, sizeof(tempMark));
head = 0;
tail = 0;
point p1, p2, p3;
p1.x = alien[p][0];
p1.y = alien[p][1];
p2.x = alien[q][0];
p2.y = alien[q][1];
queue1[tail++] = p1;
step[p1.x][p1.y] = 0;
while (head < tail)
{
p1 = queue1[head++];
if (!tempMark[p1.x][p1.y])
{
if (p1.x == p2.x && p1.y == p2.y)
{
return step[p1.x][p1.y];
}
tempMark[p1.x][p1.y] = true;
if (p1.x + 1 < w && a[p1.x + 1][p1.y] != '#')
{
p3.x = p1.x + 1;
p3.y = p1.y;
if (!tempMark[p3.x][p3.y])
{
queue1[tail++] = p3;
step[p3.x][p3.y] = step[p1.x][p1.y] + 1;
}
}
if (p1.x - 1 >= 0 && a[p1.x - 1][p1.y] != '#')
{
p3.x = p1.x - 1;
p3.y = p1.y;
if (!tempMark[p3.x][p3.y])
{
queue1[tail++] = p3;
step[p3.x][p3.y] = step[p1.x][p1.y] + 1;
}
}
if (p1.y + 1 < h && a[p1.x][p1.y + 1] != '#')
{
p3.x = p1.x;
p3.y = p1.y + 1;
if (!tempMark[p3.x][p3.y])
{
queue1[tail++] = p3;
step[p3.x][p3.y] = step[p1.x][p1.y] + 1;
}
}
if (p1.y - 1 >= 0 && a[p1.x][p1.y - 1] != '#')
{
p3.x = p1.x;
p3.y = p1.y - 1;
if (!tempMark[p3.x][p3.y])
{
queue1[tail++] = p3;
step[p3.x][p3.y] = step[p1.x][p1.y] + 1;
}
}
}
}
return -1;
}
void construct(int n)
{
for (int i = 0; i < n; i++)
{
for (int j = i; j < n; j++)
{
if (i == j)
weight[i][j] = 0;
else
{
weight[i][j] = BFS(i, j);
weight[j][i] = weight[i][j];
}
}
}
}
int prime(int n)
{
dist[0] = 0;
mark[0] = true;
for (int i = 1; i < n; i++)
dist[i] = weight[0][i];
for (int i = 1; i < n; i++)
{
int min1 = inf;
int minIndex = -1;
for (int j = 1; j < n; j++)
{
if (!mark[j] && dist[j] < min1)
{
min1 = dist[j];
minIndex = j;
}
}
sum += min1;
dist[minIndex] = 0;
mark[minIndex] = true;
for (int j = 1; j < n; j++)
if (!mark[j])
dist[j] = (weight[minIndex][j] < dist[j]) ? weight[minIndex][j] : dist[j];
}
return sum;
}
int main()
{
//freopen("t.txt", "r", stdin);
int n1;
cin >> n1;
while (n1--)
{
cin >> h >> w;
int n = 0;
memset(mark, 0, sizeof(mark));
memset(weight, inf, sizeof(weight));
char temp[51];
gets_s(temp);
for (int i = 0; i < w; i++)
{
getline(cin, a[i]);
for (int j = 0; j < h; j++)
{
if (a[i][j] == 'A' || a[i][j] == 'S')
{
alien[n][0] = i;
alien[n++][1] = j;
}
}
}
construct(n);
sum = 0;
cout << prime(n) << endl;
}
return 0;
}