题意:y行x列的迷宫中,#代表阻隔墙(不可走),空格代表空位(可走),S代表搜索起点(可走)
A代表外星人站(可走),现在要从S出发,将S和所有的A之间都连通,求路线总距离最小值
分析:可以先用bfs将所有的A,S两两之间的最短距离,题目的目的是将S与所有的A连通,使得总距离最小,
所有任选一点开始按最小生成树的算法做就行,并非非要从S点开始
注:题目输入x,y后可能有很多空格,可以用gets将多余的空格取走,开数组是尽量开大点,之前虽然开的比题目数据 稍大,但一直错,改大就AC了、、、题目数据不忍直视
#include<cstdio> #include<queue> #include<algorithm> #include<cstring> using namespace std; const int dx[]={1,0,-1,0}; const int dy[]={0,1,0,-1}; int m,n,x,y,f[1050],num[1050][1050]; //之前都是105 struct point { int i,j; }a[1050]; struct stu { int a,b,c; }t[100500]; //之前开的10050 char s[100][100]; int cmp(struct stu x1,struct stu x2) { return x1.c<x2.c; } void bfs(int star) { int i,j,k,dis[100][100],v[100][100]; queue<struct point> q; struct point d; memset(dis,0,sizeof(dis)); memset(v,0,sizeof(v)); q.push(a[star]); v[a[star].i][a[star].j]=1; while(!q.empty()){ d=q.front(); q.pop(); i=d.i; j=d.j; if(s[i][j]=='A'||s[i][j]=='S'){ t[m].a=star; t[m].b=num[i][j]; t[m++].c=dis[i][j]; } for(k=0;k<4;k++) { d.i=i+dx[k]; d.j=j+dy[k]; if(d.i>=0&&d.i<y&&d.j>=0&&d.j<x&&!v[d.i][d.j]&&s[d.i][d.j]!='#') { q.push(d); v[d.i][d.j]=1; dis[d.i][d.j]=dis[i][j]+1; } } } } int find(int r) { if(r!=f[r]) f[r]=find(f[r]); return f[r]; } int krus() { int i,k=0,sum=0,l,r; for(i=1;i<m;i++){ l=find(t[i].a); r=find(t[i].b); if(l!=r){ sum+=t[i].c; k++; if(k==n-1) break; f[l]=r; } } return sum; } int main() { int N,i,j,sum; char c[55]; scanf("%d",&N); while(N--){ scanf("%d%d",&x,&y); gets(c); //将多余空格取走 n=1; for(i=0;i<y;i++){ gets(s[i]); for(j=0;j<x;j++) if(s[i][j]=='A'||s[i][j]=='S'){ a[n].i=i; //存A或S的坐标 a[n].j=j; num[i][j]=n++; //存点的序号 } } n--; m=1; for(i=1;i<=n;i++){ f[i]=i; //初始化父节点 bfs(i); //求以i为一个顶点的所有边的权值 } sort(t+1,t+m,cmp); sum=krus(); printf("%d\n",sum); } return 0; }
poj 3026 Borg Maze (bfs + 最小生成树),布布扣,bubuko.com
时间: 2024-10-02 08:05:44