这题的测试数据非常坑,一直WA,看了discuss才知道是因为,测试数据后面有还有空格,所以在输入x,y之后要加gets(temp),这道题的解决方法是,先用BFS在查找每两点之间的最短距离,构造出一幅无向图,然后再用prim算法,求出这幅图的最小生成树的权值和。还有一个要注意的地方就是,整个room是可以没有墙的,所以要加判断边界条件(我因此RE了几次)。
代码如下:
#include<iostream>
#include<stdio.h>
#include<vector>
#include<queue>
using namespace std;
const int MAXN = 60;
const int inf = 2600;
struct M
{
char ch;
int num;
M()//在外围加一层墙,处理边界
{
ch='#';
}
}maze[MAXN][MAXN];
struct node
{
int x,y;
int num;
};
struct q
{
int x,y;
int step;
};
int graph[105][105];
vector<node> n_list;
queue<q> Q;
void bfs_update(node Node,int vetex)//BFS
{
bool vis[MAXN][MAXN];
memset(vis,false,sizeof(vis));
q a;a.x=Node.x;a.y=Node.y;
a.step = 0;Q.push(a);
while(!Q.empty())
{
a = Q.front();
Q.pop();
if(vis[a.y][a.x]==true||maze[a.y][a.x].ch=='#')
continue;
if(maze[a.y][a.x].ch=='A'||maze[a.y][a.x].ch=='S')
{
int i=maze[Node.y][Node.x].num;
int j=maze[a.y][a.x].num;
graph[j][i]=graph[i][j]=a.step;
}
vis[a.y][a.x] = true;
q b;
b=a;b.x-=1;b.step++;Q.push(b);
b=a;b.x+=1;b.step++;Q.push(b);
b=a;b.y-=1;b.step++;Q.push(b);
b=a;b.y+=1;b.step++;Q.push(b);
}
}
int prim(int n)//prim算法
{
int max_edge = 0;
int m=1;int s(0);
int s_dis[105];
for(int i=0;i!=105;i++)
{
s_dis[i] = inf;
}
bool v[105];
memset(v,false,sizeof(v));
v[s] = true;
while(m!=n)
{
int min_dis(inf);
int point(-1);
for(int i=1;i!=n;i++)
{
if(!v[i] && graph[s][i]<s_dis[i])
s_dis[i] = graph[s][i];
if(!v[i] && s_dis[i]<min_dis)
{
min_dis = s_dis[i];
point = i;
}
}
s = point;
v[s] = true;
max_edge += min_dis;
m++;
}
return max_edge;
}
int main()
{
int T;cin>>T;
while(T--)
{
int x,y;cin>>x>>y;
char st[MAXN];int n(1);
char temp[MAXN];
gets(temp);//不加这个就会WA,消除空格
for(int i=1;i!=y+1;i++)
{
gets(st);
for(int t=0,j=1;j!=x+1;j++,t++)
{
maze[i][j].ch = st[t];
if(st[t]=='A'||st[t]=='S')
{
node N;N.x=j;N.y=i;
if(st[t]=='S')
{ N.num=0;
maze[i][j].num=N.num;
}
else
{
N.num=n;
maze[i][j].num=n;
n++;
}
n_list.push_back(N);
}
}
}
for(vector<node>::size_type item=0;item!=n_list.size();item++)//以每个搜索者和外星人为起点进行BFS
bfs_update(n_list[item],n);
cout<<prim(n)<<endl;//通过邻接矩阵求最小生成树
}
return 0;
}