POJ 3026 Borg Maze bfs + 最小生成树

题意:说有一个迷宫,里面有一些外星人,外星人用字母A表示,#表示墙,不能走,空格可以走。从起点‘S’出发。在起点和A处可以分叉,问找到所有的外星人的最短路径是多少。

思路:此题其实不是太难了,可以先用bfs搜索图,然后建边,求出一点到另一点的距离,然后求最小生成树即可。最小生成树用prime和kruskal均可。关键是这道题输入需要注意。首先先输入的是列,然后是行。其次是输入列和行的后面有可能有空格,因此需要gets一下。还有就是输入字母时,因为有空格,所以不要用cin,用scanf。

代码:

  1. #include <iostream>  
  2. #include <cstdio>  
  3. #include <string.h>  
  4. #include <algorithm>  
  5. #include <queue>  
  6. using namespace std;  
  7.   
  8. #define CLR(arr,val) memset(arr,val,sizeof(arr))  
  9. const int N = 55*2;  
  10. int vis[N*2][N*2],map[N][N],father[N*2];  
  11. struct edge{  
  12.     int lp,rp,value;  
  13. }ee[15050];  
  14. struct point{  
  15.     int x,y,step;  
  16. }pp[N*2];  
  17. int row,col,numedge,numpoint;  
  18. int addx[4] = {0,0,1,-1};  
  19. int addy[4] = {1,-1,0,0};  
  20. bool fun(int x,int y){  
  21.     if(map[x][y] >= 0 && !vis[x][y])  
  22.         return true;  
  23.     return false;  
  24. }  
  25. void bfs(int posx,int posy,int id){  
  26.     CLR(vis,0);  
  27.     queue<point> qq;  
  28.     point newpp;  
  29.     newpp.x = posx;  
  30.     newpp.y = posy;  
  31.     newpp.step = 0;  
  32.     vis[posx][posy] = 1;  
  33.     qq.push(newpp);  
  34.     while(!qq.empty()){  
  35.         point tpp = qq.front();  
  36.         qq.pop();  
  37.         int tx = tpp.x;  
  38.         int ty = tpp.y;  
  39.         for(int i = 1; i < numpoint; ++i){  
  40.             if(pp[i].x == tx && pp[i].y == ty){  
  41.                 ee[numedge].lp = id;  
  42.                 ee[numedge].rp = i;  
  43.                 ee[numedge].value = tpp.step;  
  44.                 numedge++;  
  45.             }  
  46.         }  
  47.         for(int i = 0; i < 4; ++i){  
  48.           int newx = tx + addx[i];  
  49.           int newy = ty + addy[i];  
  50.           if(fun(newx,newy)){  
  51.             vis[newx][newy] = 1;  
  52.             point newp;  
  53.             newp.x = newx;  
  54.             newp.y = newy;  
  55.             newp.step = tpp.step + 1;  
  56.             qq.push(newp);  
  57.           }  
  58.         }  
  59.     }  
  60. }  
  61. bool cmp(edge a,edge b){  
  62.     return a.value < b.value;  
  63. }  
  64. int find(int x){  
  65.     if(x == father[x])  
  66.         return x;  
  67.     return find(father[x]);  
  68. }  
  69. bool Union_Set(int x,int y){  
  70.     int fx = find(x);  
  71.     int fy = find(y);  
  72.     if(fx == fy)  
  73.         return false;  
  74.     else{  
  75.       father[fx] = fy;  
  76.       return true;  
  77.     }  
  78. }  
  79. int kruskal(){  
  80.     for(int i = 1; i <= numpoint; ++i)  
  81.         father[i] = i;  
  82.     int sum = 0;  
  83.     for(int i = 0; i < numedge; ++i){  
  84.        int lx = ee[i].lp;  
  85.        int rx = ee[i].rp;  
  86.        if(Union_Set(lx,rx))  
  87.            sum += ee[i].value;  
  88.     }  
  89.   
  90.     return sum;  
  91. }  
  92. int main(){  
  93.     //freopen("1.txt","r",stdin);  
  94.     int numcase;  
  95.     scanf("%d",&numcase);  
  96.     char ch[N];  
  97.     while(numcase--){  
  98.         CLR(map,-1);  
  99.         for(int i = 0; i < N*2; ++i){  
  100.           pp[i].x = pp[i].y = pp[i].step = 0;  
  101.         }  
  102.         for(int i = 0; i < 15000; ++i){  
  103.           ee[i].lp = ee[i].rp = ee[i].value = 0;  
  104.         }  
  105.       numpoint = 1;  
  106.       numedge = 0;  
  107.       scanf("%d%d",&col,&row);  
  108.       gets(ch);  
  109.       char ss;  
  110.       for(int i = 1; i <= row; ++i){  
  111.           for(int j = 1; j <= col; ++j){  
  112.             scanf("%c",&ss);  
  113.             if(ss == '#')  
  114.                 map[i][j] = -1;  
  115.             else if(ss == ' ')  
  116.                 map[i][j] = 0;  
  117.             else{  
  118.               map[i][j] = 1;  
  119.               pp[numpoint].x = i;  
  120.               pp[numpoint].y = j;  
  121.               numpoint++;  
  122.             }  
  123.           }  
  124.           getchar();  
  125.       }  
  126.       for(int i = 1;i < numpoint; ++i){  
  127.          int posx = pp[i].x;  
  128.          int posy = pp[i].y;  
  129.          bfs(posx,posy,i);  
  130.       }  
  131.       sort(ee,ee+numedge,cmp);  
  132.       int ans = kruskal();  
  133.       printf("%d\n",ans);  
  134.     }  
  135.     return 0 ;  
  136. }  
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值