题目大概:
在迷宫里抓住所有外星人的最佳方式。
思路:
用bfs()求出所有点(包括S和所有A)之间的最短距离,再用prim最小生成树求出最短路的距离。
代码:
- #include <iostream>
- #include <string>
- #include <cstdio>
- #include <queue>
- #include <cstring>
- #include <algorithm>
- const int INF = 0x3f3f3f3f;
- using namespace std;
- int n,pp;
- char map[55][55];
- int vis[55][55],p[250][250],a[250][250],b[250],vi[250];
- int x,y,x1,y1;
- int dx[4]={0,0,1,-1};
- int dy[4]={1,-1,0,0};
- struct poin
- {
- int s,d,tt;
- };
- int bfs(int w,int e)
- {
- poin t;
- t.s=w;t.d=e;t.tt=0;
- queue<poin>q;
- vis[t.s][t.d]=1;
- q.push(t);
- poin w1,w2;
- while(!q.empty())
- { w1=q.front();
- q.pop();
- if(map[w1.s][w1.d]=='S'||map[w1.s][w1.d]=='A'){
- a[p[w][e]][p[w1.s][w1.d]]=w1.tt;
- a[p[w1.s][w1.d]][p[w][e]]=w1.tt;}
- for(int i=0;i<4;i++)
- {
- w2.s=w1.s+dx[i];
- w2.d=w1.d+dy[i];
- if(w2.s>=0&&w2.s<y&&w2.d>=0&&w2.d<x&&map[w2.s][w2.d]!='#'&&!vis[w2.s][w2.d])
- {
- vis[w2.s][w2.d]=1;
- w2.tt=w1.tt+1;
- q.push(w2);
- }
- }
- }
- }
- int prim(int qq)
- {
- memset(vi,0,sizeof(vi));
- for(int i=1;i<pp;i++)
- b[i]=a[qq][i];
- int sum=0;
- vi[qq]=1;
- for(int i=2;i<pp;i++)
- { int k=i,minn=INF;
- for(int j=1;j<pp;j++)
- {
- if(!vi[j]&&minn>b[j])
- {
- minn=b[j];
- k=j;
- }
- }
- sum+=minn;
- vi[k]=1;
- for(int j=1;j<pp;j++)
- {
- if(!vi[j]&&b[j]>a[k][j])
- {
- b[j]=a[k][j];
- }
- }
- }
- return sum;
- }
- int main()
- {
- scanf("%d",&n);
- for(int i=1;i<=n;i++)
- {
- scanf("%d%d\n",&x,&y);
- pp=1;
- for(int j=0;j<y;j++)
- {
- gets(map[j]);
- for(int k=0;k<x;k++)
- {
- if(map[j][k]=='S'||map[j][k]=='A'){
- p[j][k]=pp;
- pp++;
- }
- }
- }
- for(int i=0;i<=pp;i++)
- {
- for(int j=0;j<=pp;j++)
- {
- if(i==j){a[i][j]=0;}
- else a[i][j]=INF;
- }
- }
- for(int i=0;i<y;i++)
- {
- for(int j=0;j<x;j++)
- {
- if(map[i][j]=='S'||map[i][j]=='A')
- {memset(vis,0,sizeof(vis));
- bfs(i,j);
- }
- }
- }
- cout<<prim(1)<<endl;
- }
- return 0;
- }
本文介绍了一种解决迷宫中捕捉所有外星人问题的方法,通过使用宽度优先搜索(BFS)确定各点间的最短距离,并利用Prim算法计算最小生成树来找出最短路径。
1380

被折叠的 条评论
为什么被折叠?



