码迷,mamicode.com
首页 > 其他好文 > 详细

广度优先搜索模板(BFS)

时间:2017-11-25 17:24:14      阅读:220      评论:0      收藏:0      [点我收藏+]

标签:turn   超出   using   queue   指针   遍历   结果   统计   ++   

此模板为寻找某矩形地图从起点至终点的最小步数

 1 #include <cstdio>
 2 #include <cstring>
 3 #include <iostream>
 4 #include <vector>
 5 #include <queue>
 6 #include <set>
 7 #include <map>
 8 #include <string>
 9 #include <cmath>
10 #include <cstdlib>
11 #include <ctime>
12 #include <stack>
13 using namespace std;
14 const int MaxN = 1000;
15 const int xx[] = {0, 0, 0, -1, 1};  //15-16行:15与16行定义坐标。作用:在第36与37行,将nxt的x和y坐标向前后左右移动。
16 const int yy[] = {0, 1, -1, 0, 0};  //理解:当读入这2个数组时,i都相同,所以就相当于对x和y执行了(x+0,y+0),(x+0,y+1),(x+0,y-1),(x-1,y+0),(x+1,y+0)
17 
18 struct Point{                       //定义结构体, 该结构体含有3个变量,x和y可以理解为坐标,t是原点到该位置所移动的步数。
19     int x, y, v;
20 };
21 
22 Point que[MaxN * MaxN + 5];     //定义Point型变量结构que,该变量为 队列(重点重点重点)定义的长度为题目中矩阵的元素个数MaxN行MaxN列(+5防止溢出)。
23 Point S, T;                     //定义Point型变量结构S,T。 S:起点。T:终点。
24 char a[MaxN +5][MaxN + 5];      //定义二维数组 ,用来表示地图。
25 bool vis[MaxN + 5][MaxN + 5];   //定义二维数组,用来标记地图中每个元素是否被访问过。
26 int n, m, ans;                  //地图n行,m列。ans:统计最短路径的步数。
27 
28 void Bfs(){
29     int head = 1, tail = 0;     //定义队列的头指针(head)和尾指针(tail).用来标记当前队列元素状况,以及判定队列是否为空,应不应该结束运行。
30     que[++tail] = S;            //接上-tail小于head 并且++tail:读入起点坐标,并将尾指针后移一位。当tail=head时,标识当前队列只存在一个元素。
31     vis[S.x][S.y] = true;       //将起点标记,以免后面重新搜索到改点。
32     Point now, nxt;             //定义2个Point型变量结构。now:表示当前所在位置及步数。nxt:表示下一次移动的位置及步数。
33     while(head <= tail){        //如果队列不为空,则执行while循环。  head=tail:只有一个元素。head<tail:队列有tail-head+1个元素。
34         now = que[head]; head++;     //读入队列当前第一个坐标。并且head后移:将当前now表示的坐标移出队列,因为该坐标不等于答案并且已经完成作用。
35         for(int i = 1; i <= 4; i++){ //35-37行:将当前位置的前后左右搜索一遍。进行38-45行的处理。
36             nxt.x = now.x + xx[i];
37             nxt.y = now.y + yy[i];
38             if(nxt.x < 1 || nxt.x > n || nxt.y < 1 || nxt.y > m) continue;  //判断当前位置的前后左右是否超出地图边界。超出就跳过,进行下一次循环
39             if(vis[nxt.x][nxt.y] || a[nxt.x][nxt.y] == #) continue;       //判断当前位置是否被搜索过(vis标记),已及当前位置是不是墙,能不能走。
40             nxt.v = now.v + 1;                    //如果前面条件均满足,则将该位置的步数记录(到达该位置的步数等于上一个点的步数加一)
41             que[++tail] = nxt;                    //尾指针后移,并将该位置进入队列。准备之后对该位置的周围进行搜索。
42             vis[nxt.x][nxt.y] = true;             //标记该位置,表示已经搜索过,之后不再进行搜索。
43             if(nxt.x == T.x && nxt.y == T.y){     //判断该位置是否为终点。
44                 ans = nxt.v;                      //由于该题只要最少步数,故只统计到终点所需要的步数。
45                 return;                              //因为找到了答案了,故结束当前函数。
46             }
47         }
48     }
49 }
50 
51 int main()
52 {
53     scanf("%d %d", &n, &m);                              //读入地图长宽
54     for(int i = 1; i <= n; i++) scanf("%s", a[i] + 1);     //读入地图元素
55     for(int i = 1; i <= n; i++){                         //55-59行:遍历地图,找到起点和终点。用S和T标记。
56         for(int j = 1; j <= m; j++){                     
57             if(a[i][j] == S) S.x = i, S.y = j;
58             else if(a[i][j] == T) T.x = i, T.y = j;
59         }
60     }
61     Bfs();                                               //执行bfs搜索
62     printf("%d\n", ans);                                 //打印最终结果
63     return 0;                                            //程序终于结束啦。。。。。。。。。。。。。哈哈哈哈哈哈哈
64 }

 

广度优先搜索模板(BFS)

标签:turn   超出   using   queue   指针   遍历   结果   统计   ++   

原文地址:http://www.cnblogs.com/ScaleCX/p/7895476.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!