题目
题意:在一个y行 x列的迷宫中,有可行走的通路空格’ ‘,不可行走的墙’#’,还有两种英文字母A和S,现在从S出发,要求用最短的路径L连接所有字母,输出这条路径L的总长度。
做法:BFS+最小生成树
我的做法是先把图转换成一个由-1表示墙,0表示空格,>=1的数字表示点A和S构成的图,然后bfs求出任意两点间的距离,最后用prime算法求出答案即可。
坑点是数据的任意一行的最后都有一个空格,所以scanf(“%d\n”);的时候一定要加一个\n将多余的空格过滤掉,字符串就用gets就可以了
#include<stdio.h>
#include<string.h>
#include<string>
#include<stdlib.h>
#include<queue>
#include<iostream>
#include<algorithm>
using namespace std;
const int maxn=55;
#define ll long long
const int inf=0x3f3f3f3f;
char mapp1[maxn][maxn];
int mapp2[maxn][maxn];
int dis[maxn*maxn][maxn*maxn];
int n,m;
int tot;
int go[4][2]= {-1,0,1,0,0,-1,0,1};
void init()
{
tot=1;
memset(mapp1,0,sizeof(mapp1));
memset(mapp2,0,sizeof(mapp2));
memset(dis,inf,sizeof(dis));
}
struct node
{
int x,y;
int sum;
} e[maxn*maxn];
void bfs(int x,int y,int s)
{
//printf("%d %d %d\n",x,y,s);
int vis[maxn][maxn];
memset(vis,0,sizeof(vis));
queue<node>q;
node p;
p.x=x;
p.y=y;
p.sum=0;
vis[x][y]=1;
q.push(p);
while(!q.empty())
{
p=q.front();
q.pop();
for(int i=0; i<4; i++)
{
int X=p.x+go[i][0],Y=p.y+go[i][1];
//printf("%d %d\n",X,Y);
if(X>=0&&Y>=0&&X<n&&Y<m&&!vis[X][Y]&&mapp2[X][Y]!=-1)
{
vis[X][Y]=1;
node pp;
pp.x=X;
pp.y=Y;
pp.sum=p.sum+1;
q.push(pp);
if(mapp2[X][Y]>=1)
{
dis[s][mapp2[X][Y]]=min(pp.sum,dis[s][mapp2[X][Y]]);
//printf("%d %d\n",pp.sum,dis[s][mapp2[X][Y]]);
}
}
}
}
}
int prime()
{
int ans[maxn*maxn];
int vis[maxn*maxn];
memset(ans,inf,sizeof(ans));
memset(vis,0,sizeof(vis));
int k=1;
for(int i=1;i<tot;i++)
ans[i]=dis[1][i];
vis[1]=1;
int sum=0;
while(k<tot-1)
{
int minn=inf,index;
for(int i=1;i<tot;i++)
{
if(!vis[i]&&ans[i]<minn)
minn=ans[i],index=i;
}
//printf("%d %d\n",minn,index);
sum+=minn;
vis[index]=1;
k++;
for(int i=1;i<tot;i++)
{
if(!vis[i]&&ans[i]>dis[index][i])
ans[i]=dis[index][i];
}
}
return sum;
}
int main()
{
int t;
scanf("%d",&t);
while(t--)
{
scanf("%d%d\n",&m,&n);
init();
//getchar();
for(int i=0; i<n; i++)
{
gets(mapp1[i]);
for(int j=0; j<m; j++)
{
if(mapp1[i][j]!='#')
{
if(mapp1[i][j]=='A'||mapp1[i][j]=='S')
{
dis[tot][tot]=0;
mapp2[i][j]=tot++;
}
else
mapp2[i][j]=0;
}
else
{
mapp2[i][j]=-1;
}
}
}
for(int i=0; i<n; i++)
{
for(int j=0; j<m; j++)
{
if(mapp2[i][j]!=-1&&mapp2[i][j]!=0)
bfs(i,j,mapp2[i][j]);
}
}
printf("%d\n",prime());
}
return 0;
}