题型:搜索+图论
题意:
题意好难读的说%>_<%~
在m*n的地图中,#代表墙壁,空格代表能走的区域,只能上下左右走,求将所有的“A”以及“S”点连起来的最短路径。
分析:
首先要注意输入,显示列数然后是行数,然后用gets()吃掉scanf留下的回车符(用getchar()不行)。
记下所有的“A”以及“S”的位置后,BFS搜索出每一个“A”("S"也算“A”的一种)到其他“A”点的最短路径,存在邻接矩阵里,需要注意的是,当从一个“A”找到找到其他“A”之后,继续往下搜索出其他的“A”点知道所有的“A”点都被找出来,而不是从原来的“A”重新开始寻找,因为这样会TLE......
邻接矩阵建立好之后就用Prim算法求出最小生成树。
代码:
#include<iostream>
#include<cmath>
#include<cstdio>
#include<cstring>
#include<queue>
using namespace std;
const int INF = 0x7f7f7f7f;
int n,m;
int cnt;
char map[55][55];
bool vis[55][55];
struct Point {
int x,y,step;
} p[105];
int dir1[]= {0,0,1,-1};
int dir2[]= {1,-1,0,0};
int path[105][105],list[105];
bool check(Point a) {
if(a.x>0 && a.x<=n && a.y>0 && a.y<=m && vis[a.x][a.y]!=true && map[a.x][a.y]!='#')
return true;
else return false;
}
void bfs(Point start,int order) {
int num=0;
queue<Point> q;
Point vn,vm;
q.push(start);
vis[start.x][start.y]=true;
while(!q.empty()) {
vn=q.front();
q.pop();
for(int i=0; i<4; i++) {
vm.x=vn.x+dir1[i];
vm.y=vn.y+dir2[i];
vm.step=vn.step+1;
if(check(vm)) {
if(map[vm.x][vm.y]=='A' || map[vm.x][vm.y]=='s'){
for(int j=0;j<cnt;j++){
if(vm.x==p[j].x && vm.y==p[j].y){
path[order][j]=path[j][order]=vm.step;
num++;
break;
}
}
if(num==cnt-1) return;
}
q.push(vm);
vis[vm.x][vm.y]=true;
}
}
}
}
int main() {
int t;
scanf("%d",&t);
while(t--) {
char tmp[55];
scanf("%d%d",&m,&n);
gets(tmp);
cnt=1;
for(int i=1; i<=n; i++) {
gets(map[i]);
for(int j=1; j<=m; j++) {
if(map[i][j]=='S') {
p[0].x=i;
p[0].y=j;
p[0].step=0;
} else if(map[i][j]=='A') {
p[cnt].x=i;
p[cnt].y=j;
p[cnt++].step=0;
}
}
}
memset(path,INF,sizeof(path));
memset(list,INF,sizeof(list));
for(int i=0; i<cnt; i++) {
memset(vis,false,sizeof(vis));
bfs(p[i],i);
}
/*
for(int i=0;i<cnt;i++){
for(int j=0;j<cnt;j++){
cout<<path[i][j]<<" ";
}
cout<<endl;
}
*/
int dis,next;
int ans=0;
list[0]=-1;
int s=0;
while(1) {
dis=INF;
next=-1;
for(int i=0; i<cnt; i++) {
list[i]=min(list[i],path[i][s]);
if(list[i]<dis&&list[i]!=-1) {
dis=list[i];
next=i;
}
}
if(next==-1) break;
ans+=dis;
s=next;
list[s]=-1;
}
printf("%d\n",ans);
}
return 0;
}