图论 最短路径Dijkstra算法你还不会?一分钟教你弄懂原理。

内容干货十分多,请耐心读阅,做好笔记

原理讲解

这是一张有向图,每两个结点之间路径的权值已经标好,把0当做起始点。
那么,从结点0到结点4的最短距离是多少呢?
我想,通过肉眼观察你应该能找出答案,答案是7,结点0->结点2->结点4
可是,如果这张图在复杂一点呢?
这就需要用到最短路径Dijkstra算法。
如果我们要求两个结点之间的最短路径,除了通过一条边到达的,可不可能有通过两条边到达的路径更短,当然可能,可还有3条边,4条边呢?
我们先换个思路,考虑从结点0只有一条边连接的结点
在这里插入图片描述
从结点0一条边只能到达1,2,3这三个结点,而其中的最短路径为结点0->1长度为2。还有可能有通过2条边从结点0->1比长度2更短的吗?不可能了。因为如果要选第二条边,必须加上第一条边,而第一条边不能选2,而且肯定>2,第一条边就大于长度2,那么加上第二天边肯定也大于长度2。由此我们发现,从结点0到达结点1的最短路径的长度就为2。
但是,如果我们第一次考虑的是从结点0->2的最短路径,那么一条边为长度7,两条边的长度可不可能小于7?可能。因为第一点边7的长度不是最短,可能通过长度2更第二条边相加得到更短的路径。
所以,我们确定从结点0到其他结点的距离,不应该从结点1到结点n,而是应该每次先确定与结点0连接的最短边的结点。这样,此结点的状态可以用绿色标明,表示从初始结点0到它的最短路径已经被确定。而不选最短边则无法用绿色标明,无法确定是不是最短路径。
我们建立一个二位数组表示直接路径长度lujing[][],vis[]表示是否已经确定为从结点0到该结点的最短路径,d[x]表示从结点0到结点x的最短路径长度,
先让d[x]=一条边的lujing[0][x]
此时
lujing[0][1]=2 , , d[1]=2, vis[1]=ture. //最短为true
lujing[0][2]=6 , , d[2]=6, vis[2]=false.
lujing[0][3]=7 , , d[3]=7, vis[3]=false.
lujing[0][4]=max,d[4]=max, vis[4]=false.//max表示无穷大
lujing[1][2]=max,lujing[2][1]=max
lujing[1][3]=3,lujing[3][1]=max
lujing[1][4]=6,lujing[4][1]=max
lujing[2][3]=max,lujing[3][2]=max
lujing[2][4]=1,lujing[4][2]=max
lujing[3][4]=5,lujing[4][3]=max
lujing[i][i]=0,i从0到4
这些可以根据具体题目循环搞定

在这里插入图片描述
此时有个较短的中转站0->1,用它作为中间结点更新从0到其他结点的路径长度。并通过比较新的路径d[1]+lujing[1][x] 与旧的 d[x],
使最短路径d[x]=min(d[x],lujing[0][x])
0->1->3=5,d[1]+lujing[1][3]=5,d[3]=7,所以新的d[3]=5
0->1->4=8,d[1]+lujing[1][4]=8,d[4]=max,所以新的d[3]=5
更新完后,我们可以比较先在除了已经确定的最短路径的d[1],
从未确定最短路径(vis[x]=false)的其它d][x],
也就是从d[2],d[3],d[4]中找到最短连接长度,它就可以被确定为最短路径
d[2]=6
d[3]=7
d[2]=8
可以找到它是d[2]=6,就让vis[2]=ture,
如此循环,可以求出从结点0到每个结点的最短路径,到达不了则d[x]=max

下面是实现代码

for(int i = 1; i <= 4; i++)//一次循环确定一个最短路径d[x,]vis[x]=true
int x = 0; //标记下一个即将确定为最短路径的结点下标x
for(int j = 1; j <= 4; j++)//循环结点
if(vis[j]!=ture&&d[j]) <d [x]) x = j;//不断更改直接路径最短的下标x
vis[x] = ture;//循环完后最短直接路径已被确定
   for(int k = 1; k <= x; k++){
   d[j] = min(d[j], d[x] + lujing[x][j]);//用该点更新最短路径
   }
}

下面是一位博主分享的文章,可以去写道题练练手

第十二届蓝桥杯B组C/C++省赛 最短路径

下面是Dijlstra算法的可视化网站

算法可视化网站

原创不易,点个关注呗!

  • 19
    点赞
  • 16
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 12
    评论
PCL(Point Cloud Library)是一个开源的云处理库,提供了云数据的各种算法和工具。而MFC(Microsoft Foundation Classes)是一个用于开发Windows应用程序的C++类库。 要实现PCL云的可视化内嵌MFC,首先需要在MFC的应用程序中创建一个显示图像的控件,可以使用MFC中的CWnd派生类或自定义的继承自CWnd的窗口类。 在创建好显示云的控件后,需要通过PCL库的相关接口将云数据加载到内存中。可以使用PCL中的PointCloud类来存储云数据,使用PointCloud类的成员函数来进行云数据的操作。 接下来,可以在MFC应用程序的消息循环中,利用PCL提供的可视化工具类(如pcl::visualization::PCLVisualizer)来实现云的可视化。可以将云数据通过vtkSmartPointer<wndObj>将云数据传递给可视化对象,并利用该可视化对象的成员函数来设置云的颜色、大小、透明度等属性。 最后,通过在控件的绘制函数中调用可视化对象的成员函数来实现云的实时更新和渲染。可以将绘制函数与消息循环结合起来,使得云可以根据用户的操作实时更新显示。 总结起来,实现PCL云的可视化内嵌MFC的步骤包括:创建显示云的控件,加载云数据到内存,利用PCL提供的可视化工具类实现云的可视化,以及在控件的绘制函数中更新和渲染云。这样就能够在MFC应用程序中实现PCL云的可视化了。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 12
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

探索中前进two

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值