POJ-3026--Borg Maze

题目大意:在一个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; 
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值