广度优先搜索(BFS)

广度优先

Description:

阿狸被困在迷宫,snoopy要去救他,snoopy可以向上、下、左、右四个方向行走,每走一步(格)就要喝掉一瓶益力多。现在给它一个迷宫地图请问:snoopy最少需要多少瓶益力多才能走出迷宫?

Input:

先输入一个数t,表示测试的数据个数, 下面输入的就是t个迷宫, 每个迷宫的输入都应包含以下数据, 输入迷宫的大小 n(n<=15),表示迷宫大小为n*n。 再输入迷宫, 用大写字母“S”表示snoopy的位置, 用小写字母“E”表示阿狸被困的位置, 用“.”表示空白, 用“*”表示障碍, 你知道的阿狸和snoopy都只有一个。

Output:

输出需要的最少的益力多的瓶数m(数据保证一定有最少需要的利益多的瓶数)

Sample Input:

2
8
S..*....
.*...**.
..*.**..
.*..*..*
*..*E.**
........
.***..*.
....*...
8
S..*....
.*...**.
.**.**..
.*..*..*
*..**.**
........
.***..*.
....*..E

Sample Output:

12

16

题意分析:这题是最简单的求最短距离的题目,也就是典型的BFS问题。

广度优先搜索:http://baike.baidu.com/view/288267.htm 如果不想看这么长的文字解释,可以看一下下面的PPT:http://www.docin.com/p-542536008.html 

下面继续分析这道题目,我们挑选第二组数据进行分析。首先,我先把数据从数组下标为[1][1]的地方开始存储。让后在地图的周围“造”一堵墙(如图1)。我们还需要开一个跟地图一样大的数组visit来记录已经走过的点。将所有点初始化为0,走过的点记为1。

                                                                

图1                        图2                        图3

然后记录S的坐标。将S入队并标记visit[s.x][s.y]=1,查看S点是否等于E,不等,将队首元素pop出去;否则返回结果。然后查看与S相邻的上下左右4点(上下左右的顺序随便),如果该点不是墙(即‘*‘)并且之前没走过(visit[该点.x][该点.y]等于0),则将该点入队,标记visit[该点.x][该点.y]=1;否则不做处理。相邻的点都查看完后,再取队首元素查看该点是否等于E.......(重复做绿色部分的步骤,直到队列为空)。为了便于理解,上面贴出了图2和图3。图中的数字即为第n步到达的位置。

下面贴出源代码:

 1 #include<cstdio>
 2 #include<cstring>
 3 #include<queue>
 4 using namespace std;
 5 char map[17][17];//地图
 6 bool visit[17][17];//用来记录状态
 7 int dir[][2]={{1,0},{0,1},{-1,0},{0,-1}};//方向
 8 struct Point
 9 {   //记录点的坐标和步数
10     int x,y,cnt;
11 };
12 void BFS(int sx,int sy)
13 {
14     queue<Point> a;
15     Point now,next;
16     now.x = sx; now.y = sy; now.cnt = 0;
17     a.push(now);
18     visit[sx][sy] = 1;
19     while(!a.empty())
20     {
21         Point temp = a.front(); a.pop();
22         if(map[temp.x][temp.y] == ‘E‘)
23         {
24             printf("%d\n",temp.cnt);
25             return ;
26         }
27         for(int i = 0; i < 4; i++)
28         {
29             next.x = temp.x+dir[i][0];
30             next.y = temp.y+dir[i][1];
31             next.cnt = temp.cnt+1;
32             if((!visit[next.x][next.y]) && (map[next.x][next.y]!=‘*‘))
33             {   a.push(next); visit[next.x][next.y] = 1;}
34         }
35     }
36     return ;
37 }
38 int main(void)
39 {
40     int i,j,t,m,n;
41     scanf("%d",&t);
42     while(t--)
43     {
44         int sx,sy;
45         memset(visit,0,sizeof(visit));
46         scanf("%d",&n);
47         for(i = 1; i <= n; i++)
48             scanf("%s",&map[i][1]);
49         for(i = 0; i <= (n+1); i++)
50             for(j = 0; j <= (n+1); j++)
51             {
52                 if(map[i][j] == ‘S‘)
53                     sx = i, sy = j;
54                 if((i==0) || (j==0) || (i==n+1) || (j==n+1))
55                     map[i][j] = ‘*‘;
56             }
57         BFS(sx,sy);
58     }
59
60     return 0;
61 }

这是我做的第一道搜索题,做了一下午,才真正搞懂BFS。以前也一直不会BFS,看别人的代码都好长,有的又看不懂。还是上面红色链接里的PPT帮了大忙,不懂的多看几次PPT。下面是我做的PPT也可以看看:http://files.cnblogs.com/files/Muia/%E8%BF%B7%E5%AE%AB.ppt

时间: 2024-10-01 04:23:57

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

【算法导论】--C++实现广度优先搜索bfs

一.题目 根据上次随机生成的100个顶点的无向图和有向图,对其进行广度优先搜索. 二.理解广度优先搜索 广度优先搜索可以将其想象成水滴落入水面溅起了的一圈一圈的涟漪,是由一个起始点开始一圈一圈进行扩散搜索的. [课上老师是这样说的,大家想象一下,发现其实非常形象] 广度优先搜索总是从一个起始点出发,首先扩散这个点周围所有的邻居,然后邻居在去扩散邻居的邻居(*^-^*)...然后一直到最后将整张图都扩散完. 三.代码实现 对于第一次随机生成100个顶点的图进行了细节的修改,将每个顶点的类型改为了自

深度优先搜索DFS和广度优先搜索BFS

DFS简介 深度优先搜索,从起点开始按照某个原则一直往深处走,直到找到解,或者走不下去,走不下去则回溯到前一节点选择另一条路径走,直到找到解为止. BFS简介 广度优先搜索,从起点开始先搜索其相邻的节点,由此向外不断扩散,直到找到解为止. 举例解释 从1开始去寻找5 DFS: 原则:优先选择左手边 过程:1-2-3-4-6-4-5 BFS: 队列情况:1 2.5     5.3 5出来则找到 遍历图中所有点 DFS: 原则:优先选择左手边 过程:1-2-3-4-6-4-5 BFS: 队列情况:1

算法与数据结构基础 - 广度优先搜索(BFS)

BFS基础 广度优先搜索(Breadth First Search)用于按离始节点距离.由近到远渐次访问图的节点,可视化BFS 通常使用队列(queue)结构模拟BFS过程,关于queue见:算法与数据结构基础 - 队列(Queue) 最直观的BFS应用是图和树的遍历,其中图常用邻接表或矩阵表示,例如 LeetCode题目 690. Employee Importance: // LeetCode 690. Employee Importance/* class Employee { publi

广度优先搜索BFS

广度优先搜索可以形成一个广度优先搜索树 算法时间为O(V+E),两重循环 输入:图g,起点start(int) 需要的数据结构:队列Q.color数组(存放每个顶点的颜色) 算法过程: 1. 预处理:1)color数组的每个值都赋为white(表示没被访问过):2)队列Q为空队列 2. 处理起点: 1)color[start]=gray,gray表示顶点已被访问,但其子节点未被处理(指的是入队列):2)Q.enQueue(start) 3. 循环以下操作,直到Q为空 1)int u=Q.deQu

广度优先搜索bfs C++实现

#include<iostream>  #include<vector>  #include<map>  #include<queue>  #include<set>  using namespace std;    vector<int> bfs(map<int, vector<int> > link, int top)  {      queue<int> qe;  //队列用来记录节点的遍历顺

PAT甲级——1091 Acute Stroke (广度优先搜索BFS)

本文同步发布在CSDN:https://blog.csdn.net/weixin_44385565/article/details/94207638 1091 Acute Stroke (30 分) One important factor to identify acute stroke (急性脑卒中) is the volume of the stroke core. Given the results of image analysis in which the core regions

数据结构之 图论---基于邻接矩阵的广度优先搜索遍历(输出bfs遍历序列)

数据结构实验图论一:基于邻接矩阵的广度优先搜索遍历 Time Limit: 1000MS Memory limit: 65536K 题目描述 给定一个无向连通图,顶点编号从0到n-1,用广度优先搜索(BFS)遍历,输出从某个顶点出发的遍历序列.(同一个结点的同层邻接点,节点编号小的优先遍历) 输入 输入第一行为整数n(0< n <100),表示数据的组数. 对于每组数据,第一行是三个整数k,m,t(0<k<100,0<m<(k-1)*k/2,0< t<k),

GraphMatrix::BFS广度优先搜索

查找某一结点的邻居: virtual int firstNbr(int i) { return nextNbr(i, n); } //首个邻接顶点 virtual int nextNbr(int i, int j) //相对于顶点j的下一邻接顶点 { while ((-1 < j) && (!exists(i, --j))); return j; } //逆向线性试探(改用邻接表可提高效率) 对于图中的所有顶点,对每一个连通区域进行BFS: template <typename

关于宽搜BFS广度优先搜索的那点事

以前一直知道深搜是一个递归栈,广搜是队列,FIFO先进先出LILO后进后出啥的.DFS是以深度作为第一关键词,即当碰到岔道口时总是先选择其中的一条岔路前进,而不管其他岔路,直到碰到死胡同时才返回岔道口并选择其他岔路.接下来将介绍的广度优先搜索(Breadth First Search, BFS)则是以广度为第一关键词,当碰到岔道口时,总是先一次访问从该岔道口能直接到达的所有节结点,然后再按这些结点被访问的顺序去依次访问它们能直接到达的所有结点,以此类推,直到所有结点都被访问为止.这就跟平静的水面