POJ 3026 Borg Maze(Prim+bfs求各点间距离)
Posted Yeader
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了POJ 3026 Borg Maze(Prim+bfs求各点间距离)相关的知识,希望对你有一定的参考价值。
题目链接:http://poj.org/problem?id=3026
题目大意:在一个y行 x列的迷宫中,有可行走的通路空格’ ‘,不可行走的墙’#’,还有两种英文字母A和S,现在从S出发,要求用最短的路径L连接所有字母,输出这条路径L的总长度。
解题思路:相当于所有的字母A和S都是结点,求连接这些结点的最小距离和,是最小生成树的题目。先用BFS求各点间的距离,然后再用Prim(Kruskal也可以)求出最小距离就可以了。
注意:输完行列m和n之后,后面有一堆空格,要用gets()去掉,题目有问题,超级坑。
代码:
1 #include<iostream> 2 #include<cstdio> 3 #include<cstring> 4 #include<queue> 5 #include<algorithm> 6 using namespace std; 7 const int N=1e2+5; 8 const int MAXN=1e2+5; 9 const int INF=0x3f3f3f3f; 10 11 int n,m; 12 int d[4][2]={0,1,0,-1,-1,0,1,0}; 13 int num[N][N],cost[N][N],root[MAXN],low[MAXN]; 14 bool vis[N][N],used[MAXN]; 15 char str[N][N]; 16 17 struct node{ 18 int x,y,step; 19 node(){} 20 node(int x,int y,int step){ 21 this->x=x; 22 this->y=y; 23 this->step=step; 24 } 25 }pre; 26 27 //(x,y)点到各个点之间的最短距离 28 void bfs(int x,int y){ 29 memset(vis,false,sizeof(vis)); 30 queue<node>q; 31 q.push(node(x,y,0)); 32 vis[x][y]=true; 33 while(!q.empty()){ 34 pre=q.front(); 35 q.pop(); 36 for(int i=0;i<4;i++){ 37 int xx=pre.x+d[i][0]; 38 int yy=pre.y+d[i][1]; 39 int t=pre.step+1; 40 if(x<=0||y<=0||x>n||y>m||vis[xx][yy]||str[xx][yy]==‘#‘) 41 continue; 42 if(str[xx][yy]==‘S‘||str[xx][yy]==‘A‘) 43 cost[num[x][y]][num[xx][yy]]=t; 44 vis[xx][yy]=true; 45 q.push(node(xx,yy,t)); 46 } 47 } 48 } 49 //Prim求最小生成树 50 int Prim(int cnt){ 51 memset(used,false,sizeof(used)); 52 for(int i=1;i<=cnt;i++){ 53 low[i]=cost[1][i]; 54 } 55 used[1]=true; 56 int ans=0; 57 for(int i=1;i<cnt;i++){ 58 int k=-1; 59 for(int j=1;j<=cnt;j++){ 60 if(!used[j]&&(k==-1||low[k]>low[j])){ 61 k=j; 62 } 63 } 64 if(k==-1||low[k]==INF) return -1; 65 ans+=low[k]; 66 used[k]=true; 67 for(int j=1;j<=cnt;j++){ 68 if(!used[j]&&low[j]>cost[k][j]) 69 low[j]=cost[k][j]; 70 } 71 } 72 return ans; 73 } 74 75 int main(){ 76 int t; 77 char tmp[105]; 78 scanf("%d",&t); 79 while(t--){ 80 memset(cost,0x3f,sizeof(cost)); 81 scanf("%d%d",&m,&n); 82 //注意行列后面有一大堆空格要用gets(),出题人怕是个智。。。 83 gets(tmp); 84 int cnt=0; 85 for(int i=1;i<=n;i++){ 86 gets(str[i]+1); 87 for(int j=1;j<=m;j++){ 88 if(str[i][j]==‘S‘||str[i][j]==‘A‘) 89 num[i][j]=++cnt; 90 } 91 } 92 for(int i=1;i<=n;i++){ 93 for(int j=1;j<=m;j++){ 94 if(str[i][j]==‘S‘||str[i][j]==‘A‘){ 95 bfs(i,j); 96 } 97 } 98 } 99 printf("%d\n",Prim(cnt)); 100 } 101 return 0; 102 }
以上是关于POJ 3026 Borg Maze(Prim+bfs求各点间距离)的主要内容,如果未能解决你的问题,请参考以下文章
POJ-3026 Borg Maze---BFS预处理+最小生成树