最短路径问题,BFS,408方向,思路与实现分析
最短路径问题,BFS,408方向,思路与实现分析
继上回挖下的坑,不知道大家有没有认真看最小生成树呢?很简单,这回也讲讲正常难度的,看不懂就来这里看看,讲的很好~~
最短路径问题
说起这个问题,先说个问题吧~~
这回不修路了,这回运东西哈哈哈,abcde五个城市,a是丝绸产业重地,那么经常要往,bcde4个城市运东西,那么到各个城市怎么运送距离最近呢?图示见下~~
a分别到各个城市运送,这是一个单源最短路径问题~~
那么如果各个城市之间都有特产,需要相互的两两之间运送距离最近呢?这就是各顶点之间的最短路径问题~
所以明确一下,要搞的这三个算法当然是有适用范围的~~
单源最短路径-BFS求无权图思路
BFS其实也就是广度优先遍历,图的广度优先遍历这里我们来模拟一下~~
当然,无权图你也可以想象成权值为一的特殊带权图嘛~~
第一次遍历,我们访问的元素应该是1和6~~
第二次遍历,我们访问的元素应该是5,3和7~~
第三次遍历,我们访问的元素应该是4和8~~
BFS代码实现与分析
先来代码~~
void BFS_MIN_Distance(Graph G,int u)
{
for(i = 0;i < G.vexnum; ++i)
{
d[i] = false; //单源到各点路径长度的最短路径,先初始化,false代表不可到达
path[i] = -1; //最短路径从哪个顶点过来,先初始化
}
d[u] = 0;
visited[u] =TRUE; //标记顶点u已被标记
EnQueue(Q,u);//顶点u入队列
while(!isEmpty(Q))//主过程
{
DeQueue(Q,u);//顶点u出队列
for(w = FirstNeighbor(G,u); w >= 0; w = NextNeighbor(G,u,w))
{ //遍历当前出队列的元素的所有邻接顶点,第一次为遍历顶点u的所有邻接顶点
//当前出队列的元素即跳出for循环之后,再进入for循环时,本例中,u即为1号元素
if(!visited[w]) //w为u为尚未访问的邻接顶点
{
d[w] = d[u] +1;//路径长度加1
path[w] = u; //最短路径为u到w
visited[w] = TRUE;//标记顶点w已被标记
EnQueue(Q,w);//顶点w入队列
}
}
}
}
我们需要列出3块内容帮助我们分析~~
visited数组:
1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | |
---|---|---|---|---|---|---|---|---|
visited | false | false | false | false | false | false | false | false |
队:开始的时候没有元素~~
d[]和path[]数组
1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | |
---|---|---|---|---|---|---|---|---|
d[] | false | false | false | false | false | false | false | false |
path[] | -1 | -1 | -1 | -1 | -1 | -1 | -1 | -1 |
分析一下到while主过程之前,我们做的事情~~
visited数组:
1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | |
---|---|---|---|---|---|---|---|---|
visited | false | true | false | false | false | false | false | false |
队: 2 ,u为2
d[]和path[]数组
1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | |
---|---|---|---|---|---|---|---|---|
d[] | false | 0 | false | false | false | false | false | false |
path[] | -1 | -1 | -1 | -1 | -1 | -1 | -1 | -1 |
那么此时进入while循环~~
第一次while循环,2出队~~
队: 空,此时2出队了~~
进入for循环~~
第一次for,u为2,第一个邻接顶点为1,并且1尚未访问,所以路径长度加1,最短路径为u到w,即2到1,标记1已访问,1入队,w=NextNeighbor,还有邻接顶点,所以继续~~
第二次for,第二个u的邻接顶点,为6,并且6尚未访问所以路径长度加1,最短路径为u到w,即2到6,标记6已访问,6入队,w=NextNeighbor,没有邻接顶点了所以跳出~~
此时
visited数组:
1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | |
---|---|---|---|---|---|---|---|---|
visited | true | true | false | false | false | true | false | false |
队: 1,6 ,队头为1,所以u为1
d[]和path[]数组
1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | |
---|---|---|---|---|---|---|---|---|
d[] | 1 | 0 | false | false | false | 1 | false | false |
path[] | 2 | -1 | -1 | -1 | -1 | 2 | -1 | -1 |
第二次while
1出队~~
进入for循环~~
第一次for,u为1,第一个邻接顶点为2,但是2已被访问,所以不执行if内语句,w=NextNeighbor,还有邻接顶点,所以继续~~
第二次for,第二个u的邻接顶点,为5,5尚未访问所以路径长度加1,此时因为d[u]初始为1,所以为1+1=2,最短路径为u到w,即1到5,标记5已访问,5入队,w=NextNeighbor,没有邻接顶点了所以跳出~~
此时
visited数组:
1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | |
---|---|---|---|---|---|---|---|---|
visited | true | true | false | false | true | true | false | false |
队: 6 ,5,队头为6,所以u为6
d[]和path[]数组
1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | |
---|---|---|---|---|---|---|---|---|
d[] | 1 | 0 | false | false | 2 | 1 | false | false |
path[] | 2 | -1 | -1 | -1 | 1 | 2 | -1 | -1 |
第三次while~~
6出队,再进行for循环,那么之后就会变成~~
visited数组:
1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | |
---|---|---|---|---|---|---|---|---|
visited | true | true | true | false | true | true | true | false |
队: 5,3,7队头为5,所以u为5
d[]和path[]数组
1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | |
---|---|---|---|---|---|---|---|---|
d[] | 1 | 0 | 2 | false | 2 | 1 | 2 | false |
path[] | 2 | -1 | 6 | -1 | 1 | 2 | 6 | -1 |
第四次whlie~~
5,出队,再进行for,没有邻接顶点,所以没有改变~~
visited数组:
1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | |
---|---|---|---|---|---|---|---|---|
visited | true | true | true | false | true | true | true | false |
队: 3,7队头为3,所以u为3
d[]和path[]数组
1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | |
---|---|---|---|---|---|---|---|---|
d[] | 1 | 0 | 2 | false | 2 | 1 | 2 | false |
path[] | 2 | -1 | 6 | -1 | 1 | 2 | 6 | -1 |
第五次while~~
3出队,进行for,此时~~
visited数组:
1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | |
---|---|---|---|---|---|---|---|---|
visited | true | true | true | true | true | true | true | false |
队: 7队头为7,所以u为7
d[]和path[]数组
1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | |
---|---|---|---|---|---|---|---|---|
d[] | 1 | 0 | 2 | 3 | 2 | 1 | 2 | false |
path[] | 2 | -1 | 6 | 3 | 1 | 2 | 6 | -1 |
第六次whlie~~
7出队,进行for,此时~~
visited数组:
1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | |
---|---|---|---|---|---|---|---|---|
visited | true | true | true | true | true | true | true | true |
队: 没有元素入队,队空了~~
d[]和path[]数组
1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | |
---|---|---|---|---|---|---|---|---|
d[] | 1 | 0 | 2 | 3 | 2 | 1 | 2 | 3 |
path[] | 2 | -1 | 6 | 3 | 1 | 2 | 6 | 7 |
此时队空,跳出while,执行成功~~
此时,我们得到了d[]和path[]数组~~
1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | |
---|---|---|---|---|---|---|---|---|
d[] | 1 | 0 | 2 | 3 | 2 | 1 | 2 | 3 |
path[] | 2 | -1 | 6 | 3 | 1 | 2 | 6 | 7 |
比如我们看4号元素,即可知~~
2到4号元素的最短路径为长度d[4] = 3;
2到4号元素的最短路径为: 看4号元素path[4]为3,4 <- 3,再看3号元素path[3]为6,3 <- 6 ,再看6号元素path[6]为2,6 <- 2,所以2到4的最短路径为:2 -> 6 -> 3 -> 4~~
写到这才发现一写就挺多的,那Dijkstra,Floyd算法就下次再写咯~~
最短路径问题,BFS,408方向,思路与实现分析的更多相关文章
- 最小生成树,Prim算法与Kruskal算法,408方向,思路与实现分析
最小生成树,Prim算法与Kruskal算法,408方向,思路与实现分析 最小生成树,老生常谈了,生活中也总会有各种各样的问题,在这里,我来带你一起分析一下这个算法的思路与实现的方式吧~~ 在考研中呢 ...
- poj 2251 三维地图最短路径问题 bfs算法
题意:给你一个三维地图,然后让你走出去,找到最短路径. 思路:bfs 每个坐标的表示为 x,y,z并且每个点都需要加上时间 t struct node{ int x, y, z; int t;}; b ...
- Z1. 广度优先搜索(BFS)解题思路
/** BFS 解题思路 特点:从某些特定的节点开始,感染相邻的节点; 被感染的节点,再感染其相邻的节点,以此类推. 题目常见于数据结构包括 二维数组.树.图 **/ /** 1). 二维数组特定节点 ...
- CDOJ 1964 命运石之门【最短路径Dijkstra/BFS】
给定数字n,m(1<=n,m<=500000) 将n变为n*2花费2,将n变为n-3花费3,要求过程中所有数字都在[1,500000]区间内. 求将n变为m的最少花费 思路:建图 将每个数 ...
- POJ 1101 The Game(BFS+判方向)
The Game Description One morning, you wake up and think: "I am such a good programmer. Why ...
- 挑战程序设计——迷宫的最短路径(BFS)
题目详情 Description 给定一个大小为 N * M 的迷宫.迷宫由通道和墙壁组成,每一步可以向邻接的上下左右四格的通道移动.请求出从起点到终点所需的最小步数 限制条件: N,M <= ...
- hdu1180 优先队列bfs+判断方向
诡异的楼梯 Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 131072/65536 K (Java/Others)Total Subm ...
- B - ACM小组的古怪象棋 【地图型BFS+特殊方向】
ACM小组的Samsara和Staginner对中国象棋特别感兴趣,尤其对马(可能是因为这个棋子的走法比较多吧)的使用进行深入研究.今天他们又在 构思一个古怪的棋局:假如Samsara只有一个马了,而 ...
- E - A strange lift 【数值型BFS+上下方向】
There is a strange lift.The lift can stop can at every floor as you want, and there is a number Ki(0 ...
随机推荐
- URL分发器(视图层)
目录 视图 URL映射 path函数 URL中传入参数 普通传入参数 变量形式传入参数 URL中包含另一个urls模块 URL命名.URL反转.应用命名空间 视图 视图一般都写在 app 的 vi ...
- 子域名探测工具Aquatone的使用
目录 Aquatone Aquatone的安装 Aquatone的使用 子域名爆破 端口扫描
- SQL必学必会笔记 —— 基础篇
基础篇 SQL语言按照功能划分 DDL(DataDefinitionLanguage),也就是数据定义语言,它用来定义我们的数据库对象,包括 数据库.数据表和列.通过使用DDL,可以创建,删除和修改数 ...
- 21.Quick QML-FileDialog、FolderDialog对话框
1.FileDialog介绍 Qt Quick中的FileDialog文件对话框支持的平台有: 笔者使用的是Qt 5.8以上的版本,模块是import Qt.labs.platform 1.1. 它的 ...
- 用scanf_s判断输入数据是否合法
用scanf_s判断输入数据是否合法 对用户输入的整数进行求和.当用户输入任意字符时,结束程序并打印结果. A. 用户可以输入整数和浮点数 B. 用户可以在同一行输入多个数字,数字之间可以是任意一个分 ...
- Educational Codeforces Round 96 (Rated for Div. 2)
A. Number of Apartments 题意:求方程的解 思路:直接模拟就行 代码: #include<iostream> #include<cstdio> #incl ...
- 获取CPU频率
#include <stdio.h> #include <string.h> float get_cpu_clock_speed() { FILE *fp; char buff ...
- 并发王者课 - 青铜 2:峡谷笔记 - 简单认识Java中的线程
在前面的<兵分三路:如何创建多线程>文章中,我们已经通过Thread和Runnable直观地了解如何在Java中创建一个线程,相信你已经有了一定的体感.在本篇文章中,我们将基于前面的示例代 ...
- Linux 根目录所在分区被脏数据占满
背景: 公司在做一个项目,大概功能就是一个通行闸机的人脸识别系统,要经过门禁的人注册了之后,系统就会存储一张原始的图片在服务器的数据文件夹里面,包括了永久的存储和一些访客注册临时存储.一天周五的时 ...
- 11.4 iftop:动态显示网络接口流量信息
iftop是一款实时流量监控工具,可用于监控TCP/IP连接等,必须以root用户的身份运行. 一般最小化安装系统都是没有这个命令的,需要使用yum命令额外安装,而且还要从epel源下载. ift ...