POJ-3026--Borg Maze

本文介绍了一种解决迷宫寻路问题的算法,通过BFS和Prim算法找到从起点S到所有字母A的最短路径,并计算路径总长度。
题目大意:在一个y行 x列的迷宫中,有可行走的通路空格’ ‘,不可行走的墙’#’,还有两种英文字母A和S,现在从S出发,要求用最短的路径L连接所有字母,输出这条路径L的总长度。

Sample Input


6 5 

##### 

#A#A## 

# # A# 

#S  ## 

##### 

 7 7 

##### 

#AAA###

#    A# 

# S ### 

#    

#AAA### 

#####  

Sample Output


11

AC Code : bfs+prim   Memory:260K   Time:16MS

#include <iostream> 

#include <cstdio> 

#include <cstring> 

#include <queue> 

#define Max 55 

#define Inf 0x7fffffff 

using namespace std; 

char map[Max][Max];  //0--'#',1--' ',2--'A',-1--'S' 

int dis[102][102];
//int dis[2500][2500]; 

int hash[Max][Max]; 

int dist[Max][Max]; 

int x,y;
int num;            //记录A点的个数 

int move[4][2]={{-1,0},{1,0},{0,-1},{0,1}}; 

void init() 

{ int i,j;
    char C;
    char str[Max]; 

  scanf("%d%d",&y,&x); 

  memset(dis,0,sizeof(dis));
    memset(hash,0,sizeof(hash)); 

  num=0; 

  for(i=1;i<=x;i++)
    map[i][0]=map[i][y+1]='#'; 

  for(j=0;j<=y+1;j++)
    map[0][j]=map[x+1][j]='#'; 

  for(i=1;i<=x;i++) 

  {
        gets(str); 

    for(j=1;j<=y;j++) 

    {  C=getchar(); 

       if(C=='S'||C=='A') {
                num++;
                hash[i][j]=num;
            } 

      map[i][j]=C; 

     } 

  } 

} 

int que_a[2501]; 

int que_b[2501]; 

void bfs(int a,int b) 

{  int i;
    int a1,b1;
    int a2,b2;

    int head,tail; 

   head=0,tail=0;

    memset(dist,0,sizeof(dist)); 

   que_a[tail]=a;
    que_b[tail++]=b; 

    int s1=hash[a][b];         //源点index 

    int s2; 

    while(head<tail) 

    {  a1=que_a[head];
        b1=que_b[head++]; 

      if(hash[a1][b1]) 

      {  s2=hash[a1][b1];           //现在求的点的index 

        dis[s1][s2]=dis[s2][s1]=dist[a1][b1]; 

       } 

      for(i=0;i<4;i++) 

      {  a2=a1+move[i][0];
            b2=b1+move[i][1]; 

        if(a2==a&&b2==b)
                continue; 

        if(map[a2][b2]=='#'||dist[a2][b2])
                continue; 

       dis[hash[a1][b1]][hash[a2][b2]]=1; 

       dis[hash[a2][b2]][hash[a1][b1]]=1; 

       dist[a2][b2]=dist[a1][b1]+1; 

       que_a[tail]=a2;
            que_b[tail++]=b2; 

       } 

    } 

 return; 

} 

int value; 

void prim() 

{  bool p[Max*Max];
    int dist2[Max*Max];
    int s,k,index,min; 

   value=0,k=0,s=1; 

   memset(p,0,sizeof(p)); 

   for(int i=0;i<=num+1;i++)
    dist2[i]=Inf;
    //默认先将1号点放入最小生成树 

   while(1) 

  {  p[s]=1;
        k++; 

     if(k==num)
        break; 

     min=Inf,index=0; 

     for(int i=2;i<=num;i++) 

     {  if(p[i])
            continue; 

       if(dist2[i]>dis[s][i])
                dist2[i]=dis[s][i]; 

       if(dist2[i]<min)
            {
                min=dist2[i];
                index=i;
            } 

      } 

     value+=min; 

     s=index; 

   } 

} 

int main() 

{  int test; 

   scanf("%d",&test); 

   while(test--) 

   {   init(); 

       for(int i=1;i<=x;i++) 

            for(int j=1;j<=y;j++) 

                if(hash[i][j])
                    bfs(i,j); 

       prim(); 

       rintf("%d\n",value); 

   } 

   return 0; 

}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值