POJ 3026 Borg Maze 普利姆 + BFS

  题意:一群人在地图上走啊走  每走到一个 ‘S’ 或者 ‘A’  就可以分开一次 最多分成四个小队(因为只有四个方向可以走),直到找到所有的‘A’,输出能找到所有‘A’的最小的步数。

  注意,新的小队的移动次数从0开始计算。

  显然,最小生成树算法。每一组相邻的'A'都可以看成是一个整体,这些独立的整体组成了一个图,在这个图上选取一个最小生成树,这颗最小生成树的边的权值之和即为答案。

  此题新颖之处在于寻找最短的那条边。一提到最短边显然要用到BFS。

  开始的时候以‘s’为BFS的起点出发  找到离它最近的那个‘A’,把这一组‘A’和‘s’看成一个整体,再以这个新的整体为BFS的起点出发,继续寻找下一组‘A’........知道找到所有的‘A’。

  此题还有一个坑爹之处在于 输入行数和列数之后  要用gets() 吃掉多余的空格,而不是用getchar()........

  Ac_code  C++  0MS  260KB

  

1 #include <iostream>
  2 #include <algorithm>
  3 #include <cmath>
  4 #include <cstdio>
  5 #include <cstring>
  6 #include <cstdlib>
  7 #include <queue>
  8 
  9 using namespace std;
 10 
 11 char map[60][60];
 12 
 13 int vis[60][60];
 14 
 15 struct N
 16 {
 17     int r,c,ans;
 18 };
 19 
 20 queue<N> q;
 21 
 22 int jr[] = { 0,-1, 0, 1};
 23 int jc[] = {-1, 0, 1, 0};
 24 
 25 int Min;
 26 
 27 void updata(N l,int r,int c)
 28 {
 29     while(!q.empty())
 30         q.pop();
 31 
 32     queue<N> tq;
 33     N t,p;
 34 
 35     tq.push(l);
 36 
 37     vis[l.r][l.c] = 1;
 38 
 39     while(!tq.empty())
 40     {
 41         t = tq.front();
 42         tq.pop();
 43         for(int i = 0;i < 4; i++)
 44         {
 45             p.c = t.c + jc[i];
 46             p.r = t.r + jr[i];
 47 
 48             if(p.c >= 1 && p.c <= c && p.r >= 1 && p.r <= r && map[p.r][p.c] == 'A' && vis[p.r][p.c] == 0)
 49             {
 50                 Min++;
 51 
 52                 vis[p.r][p.c] = 1;
 53 
 54                 p.ans = 0;
 55                 tq.push(p);
 56             }
 57         }
 58     }
 59 
 60     int i,j;
 61     for(i = 1;i <= r; i++)
 62         for(j = 1;j <= c; j++)
 63         {
 64             if(vis[i][j] == 1)
 65             {
 66                 p.ans = 0;
 67                 p.r = i;
 68                 p.c = j;
 69                 q.push(p);
 70             }
 71             else if(vis[i][j] == 2)
 72             {
 73                 vis[i][j] = 0;
 74             }
 75         }
 76 }
 77 
 78 void bfs(int sr,int sc,int r,int c)//bfs寻找最短路
 79 {
 80     while(!q.empty())
 81         q.pop();
 82 
 83     N t,p;
 84 
 85     t.r = sr;
 86     t.c = sc;
 87     t.ans = 0;
 88 
 89     vis[t.r][t.c] = 1;
 90 
 91     int i;
 92 
 93     q.push(t);
 94 
 95     while(!q.empty())
 96     {
 97         t = q.front();
 98         q.pop();
 99         for(i = 0;i < 4; i++)
100         {
101             p.c = t.c + jc[i];
102             p.r = t.r + jr[i];
103             p.ans = t.ans+1;
104 
105             if(p.c >= 1 && p.c <= c && p.r >= 1 && p.r <= r && map[p.r][p.c] != '#' && vis[p.r][p.c] == 0)
106             {
107                 vis[p.r][p.c] = 2;
108 
109                 q.push(p);
110                 if(map[p.r][p.c] == 'A')//将此部分’A‘全都加到队列中 并标记。
111                 {
112                     Min += p.ans;
113 
114                     updata(p,r,c);
115                     break;
116                 }
117             }
118         }
119     }
120 }
121 
122 int main()
123 {
124     int T;
125 
126     int r,c,sr,sc;
127 
128     int i,j;
129     char temp[51];
130     cin>>T;
131     while(T--)
132     {
133         Min = 0;
134         cin>>c>>r;
135         gets(temp);
136         for(i = 1;i <= r; i++)
137             gets(map[i]+1);
138         for(i = 1;i <= r; i++)
139             for(j = 1;j <= c; j++)
140             {
141                 if(map[i][j] == 'S')
142                 {
143                     sr = i;
144                     sc = j;
145                     break;
146                 }
147             }
148         memset(vis,0,sizeof(vis));
149 
150         bfs(sr,sc,r,c);
151         cout<<Min<<endl;
152     }
153     return 0;
154 }
View Code

 

posted @ 2013-08-07 09:12  好小孩  阅读(193)  评论(0编辑  收藏  举报