题目链接:点击打开链接
题意:一个地图,地图里面有外星人,问你找到所有外星人的最短路。你是一大波人,人可以在找到外星人或着起点时,分成若干队伍。
题解:最小生成树 + bfs。其实题意就是让你把所有的点链接起来最小值。最小生成树的权值 就是题目答案。
煞笔题目。垃圾数据,毁我青春,正在写这道题的小伙伴,就不要写了,题目本身没难度,数据地图大小的m,n后莫名加空格就是死活过不去。
#include<iostream>
#include<stdio.h>
#include<string.h>
#include<algorithm>
#include<queue>
#define maxxy 55
#define maxn 105
#define inf 0x3f3f3f3f
using namespace std;
int n;
int map[maxxy][maxxy]={0};
int dis[maxn][maxn]={0};
int num[maxxy][maxxy];
struct point
{
int x;
int y;
}a[maxn];
struct edge
{
int s;int e;int v;
}b[maxn*maxn];
int x,y;
int move[4][2]={{1,0},{-1,0},{0,1},{0,-1}};
int f[maxn]={0};
int find(int x)
{
return f[x]==x?x:f[x]=find(f[x]);
}
void Union(int a,int b)
{
int fa=find(a);
int fb=find(b);
f[fa]=fb;
return;
}
bool cmp(edge a,edge b)
{
return a.v<b.v;
}
void bfs(int k){
bool vis[maxxy][maxxy]={0};
int v[maxxy][maxxy]={0};
queue<point>q;
q.push(a[k]);
vis[a[k].x][a[k].y]=1;
v[a[k].x][a[k].y]=0;
while(!q.empty()){
for(int i=0;i<4;i++){
point l;
l.x=q.front().x+move[i][1];
l.y=q.front().y+move[i][0];
if(l.x>x||l.x<1||l.y>y||l.y<1)
continue;
if(vis[l.x][l.y])
continue;
if(map[l.x][l.y]==1)
continue;
v[l.x][l.y]=v[q.front().x][q.front().y]+1;
q.push(l);
vis[l.x][l.y]=1;
if(map[l.x][l.y]==2){
dis[k][num[l.x][l.y]]=v[l.x][l.y];
}
}
q.pop();
}
}
int kruskal(){
for(int i=0;i<=n;i++){
f[i]=i;
}
int s=0;
int num=0;
for(int i=1;i<=n;i++){
for(int j=i+1;j<=n;j++){
num++;
b[num].s=i;
b[num].e=j;
b[num].v=dis[i][j];
}
}
sort(b+1,b+num+1,cmp);
int sun = 0;
for(int i=1;i<=num;i++){
if(find(b[i].s)==find(b[i].e))continue;
Union(b[i].s,b[i].e);
sun ++;s+=b[i].v;
if(sun == n - 1)
return s;
}
}
int main(){
int test;
scanf("%d",&test);
while(test--){
char c;
scanf("%d %d",&x,&y);
while(c!='\n'){
scanf("%c",&c);
}
n=1;
memset(map,0,sizeof(map));
memset(dis,0x3f,sizeof(dis));
for(int i=1;i<=y;i++){
for(int j=0;j<=x;j++){
scanf("%c",&c);
if(c=='#')
map[j+1][i]=1;
if(c=='A'){
map[j+1][i]=2;
n++;
a[n].x=j+1;a[n].y=i;
num[j+1][i]=n;
}
if(c=='S'){
map[j+1][i]=2;
a[1].x=j+1;a[1].y=i;
num[j+1][i]=1;
}
}
}
for(int i=1;i<=n;i++){
bfs(i);
}
cout<<kruskal()<<endl;
}
}