广度优先搜索模板(BFS)

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

 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 }
时间: 2024-11-08 10:07:21

广度优先搜索模板(BFS)的相关文章

[C++]广度优先搜索(BFS)(附例题)

广度优先搜索(BFS)(附例题) 问题产生: Isenbaev是国外的一个大牛. 现在有许多人要参加ACM ICPC. 一共有n个组,每组3个人.同组的3个人都是队友. 大家都想知道自己与大牛的最小距离是多少. 大牛与自己的最小距离当然是0.大牛的队友和大牛的最小距离是1.大牛的队友的队友和大牛的最小距离是2--以此类推. 如果实在和大牛没有关系的只好输出undefined了. 第一行读入n.表示有n个组.1 ≤ n ≤ 100 接下来n行,每行有3个名字,名字之间用空格隔开.每个名字的开头都是

迷宫问题(maze problem)——深度优先(DFS)与广度优先搜索(BFS)求解

1.问题简介 给定一个迷宫,指明起点和终点,找出从起点出发到终点的有效可行路径,就是迷宫问题(maze problem). 迷宫可以以二维数组来存储表示.0表示通路,1表示障碍.注意这里规定移动可以从上.下.左.右四方方向移动.坐标以行和列表示,均从0开始,给定起点(0,0)和终点(4,4),迷宫表示如下: int maze[5][5]={ {0,0,0,0,0}, {0,1,0,1,0}, {0,1,1,0,0}, {0,1,1,0,1}, {0,0,0,0,0} }; 那么下面的迷宫就有两条

队列的JS实现及广度优先搜索(BFS)的实现

队列是先进先出(FIFO)的数据结构,插入操作叫做入队,只能添加在队列的末尾:删除操作叫做出队,只能移除第一个元素.在JS中,用数组可以很简单的实现队列. function Queue () { this.queue = []; } // 增加 Queue.prototype.enQueue = function(x) { this.queue.push(x); return true; } // 删除 Queue.prototype.deQueue = function() { if(this

深度优先搜索(DFS)与广度优先搜索(BFS)的Java实现

1.基础部分 在图中实现最基本的操作之一就是搜索从一个指定顶点可以到达哪些顶点,比如从武汉出发的高铁可以到达哪些城市,一些城市可以直达,一些城市不能直达.现在有一份全国高铁模拟图,要从某个城市(顶点)开始,沿着铁轨(边)移动到其他城市(顶点),有两种方法可以用来搜索图:深度优先搜索(DFS)和广度优先搜索(BFS).它们最终都会到达所有连通的顶点,深度优先搜索通过栈来实现,而广度优先搜索通过队列来实现,不同的实现机制导致不同的搜索方式. 1.1 深度优先搜索 深度优先搜索算法有如下规则: 规则1

Z1. 广度优先搜索(BFS)解题思路

/** BFS 解题思路 特点:从某些特定的节点开始,感染相邻的节点; 被感染的节点,再感染其相邻的节点,以此类推. 题目常见于数据结构包括 二维数组.树.图 **/ /** 1). 二维数组特定节点感染相邻的节点,即上下左右四个方向,可设定变化数组如下 int[] dr = new int[]{-1, 0, 1, 0}; int[] dc = new int[]{0, -1, 0, 1}; 2). 二维数组特定节点感染包围它的节点,即八个方法, 可设定变化数组如下: int[] dr = ne

Leetcode之广度优先搜索(BFS)专题-1162. 地图分析(As Far from Land as Possible)

BFS入门详解:Leetcode之广度优先搜索(BFS)专题-429. N叉树的层序遍历(N-ary Tree Level Order Traversal) 你现在手里有一份大小为 N x N 的『地图』(网格) grid,上面的每个『区域』(单元格)都用 0 和 1 标记好了.其中 0 代表海洋,1 代表陆地,你知道距离陆地区域最远的海洋区域是是哪一个吗?请返回该海洋区域到离它最近的陆地区域的距离. 我们这里说的距离是『曼哈顿距离』( Manhattan Distance):(x0, y0) 

Leetcode之广度优先搜索(BFS)专题-994. 腐烂的橘子(Rotting Oranges)

BFS入门详解:Leetcode之广度优先搜索(BFS)专题-429. N叉树的层序遍历(N-ary Tree Level Order Traversal) 在给定的网格中,每个单元格可以有以下三个值之一: 值 0 代表空单元格: 值 1 代表新鲜橘子: 值 2 代表腐烂的橘子. 每分钟,任何与腐烂的橘子(在 4 个正方向上)相邻的新鲜橘子都会腐烂. 返回直到单元格中没有新鲜橘子为止所必须经过的最小分钟数.如果不可能,返回 -1. 示例 1: 输入:[[2,1,1],[1,1,0],[0,1,1

广度优先搜索(bfs)

学了将近半年的信息了,昨天猛地间发现我好像不会搜索.... 这就意味着我在noip的时候连暴力都不会打...为了避免这种事情的发生,我决定一定要好好学搜索.. 好了,废话不多说了,下面开始我们的正式话题:广度优先搜索 1.前言 广度优先搜索其实是一种用来遍历连通图的一种算法,它的思想是从一个顶点V0开始,辐射状地优先遍历其周围较广的区域,故得名.                       貌似有的东西就真的跟徐大佬说的一样:说不清楚,只能靠自己去做题才能真正理解. 所以,如果我说的你不是很明白

广度优先搜索(BFS)----------------(TjuOj1140_Dungeon Master)

这次整理了一下广度优先搜索的框架,以后可以拿来直接用了.TjuOj1140是一个三维的迷宫题,在BFS时我增加了一个控制数组,用来对队列的出队进行控制,确保每次出队的结点均为同一步长的结点,个人认为比较适合这种迷宫搜索题. BFS部分的代码如下: int BFS ( node S , node T ) { int s = 1; //充当指针作用 memset(n,0,sizeof(n)); n[s] = 1; //初始化当前距离为1的点数为1(即原点) node now = S; visit[n

图的广度优先搜索(BFS)

把以前写过的图的广度优先搜索分享给大家(C语言版) 1 #include<stdio.h> 2 #include<stdlib.h> 3 #define MAX_VERTEX_NUM 20 4 #define MAXQSIZE 100 5 #define OK 1 6 typedef char VertexType; 7 typedef int QElemType; 8 9 typedef struct ArcNode//边结点 10 { 11 int adjvex; 12 str