最短距离问题(Dijkstra算法)

本文详细介绍了Dijkstra算法,一种用于寻找单源最短路径的算法,适用于非负权重的图。文章通过逐步解析算法过程,解释了如何从起点逐步确定到其他点的最短路径,并提供了实例分析和代码实现。
摘要由CSDN通过智能技术生成

题目链接:

https://begin.lydsy.com/JudgeOnline/problem.php?cid=1318&pid=10

同样的题哈,不一样的解法,也总算是学了Dijkstra了。
[送上一句迟到的祝福:新春快乐]

Problem K: 最短路径问题

Time Limit: 1 Sec Memory Limit: 128 MB

Description

平面上有n个点(n<=100),每个点的坐标均在-10000~10000之间。其中的一些点之间有连线。若有连线,则表示可从一个点到达另一个点,即两点间有通路,通路的距离为两点间的直线距离。现在的任务是找出从一点到另一点之间的最短路径。

Input

共n+m+3行,其中:
第一行为整数n。
第2行到第n+1行(共n行),每行两个整数x和y,描述了一个点的坐标。
第n+2行为一个整数m,表示图中连线的个数。
此后的m行,每行描述一条连线,由两个整数i和j组成,表示第i个点和第j个点之间有连线。
最后一行:两个整数s和t,分别表示源点和目标点。

Output

仅一行,一个实数(保留两位小数),表示从s到t的最短路径长度。

Sample Input

5
0 0
2 0
2 2
0 2
3 1
5
1 2
1 3
1 4
2 5
3 5
1 5

Sample Output

3.41

HINT

1.题目分析

[若还不了解此模板题,请去吐槽本蒟蒻博客最短路(Floyed-Warshall)]

好了,进入正题:

1. 首先了解一下Dijkstra:

Dijkstra算法 O(N2
用来计算从一个点到其他所有点的最短路径的算法,是一种单源最短路径算法,也就是说,只能计算起点只有一个的情况。[书上原话]
同样不能处理负边权。

2. 算法描述:

设起点为s,dis[v]表示从s到v的最短路径,pre[v]为v的前驱节点,用来输出路径,n为总点个数。
(a)初始化:dis[v]=∞(v≠s,显然到起点距离不可能为∞);dis[s]=0(到起点距离为0);pre[s]=0;(起点没有前驱)
(b)for i=1 to (n or n-1) do
①在没有被访问的点中找一个顶点u使得dis[u]最小;
(PS:因为你的开头不小,后面自然就会大,有点像贪心)
②将u标记为当前已确定最短路径;(这里不能太目光短浅)
for v=1 to n do
//这里就是为了避免目光短浅,每个点都枚举,因为当前只有u为已确定最短路径,其它点都可能被u所修改
if (dis[v]>dis[u]+dis[u][v])
{
dis[v]>dis[u]+dis[u][v];
//枚举以u为“中转点”的未确定最短路径的点v
pre[v]=u;
//更新前驱点
}
(c)算法结束,dis[v]为s到v的最短距离,pre[v]为v的前驱点,用来输出路径。

3. 算法分析&实例讲解:

1.我们的Dijkstra也是与Floyed差不多,运用“中转点”的思想,但不同的是,我们把起点s也作为一个特殊的“中转点”,而且我们是一步一步往后推最短路。
显然我们可以知道,从s到t的最短路径上,必先经过一个“中转点”v,那么我们在求出到t的最短路时,必先确定到v的最短路,换句话说:
如果起点到某一点v的最短路要经过v0,那么其“中转点”v0一定是于v确定了的最短路径点。
[是不是很绕,没关系,我们画个样例就清楚了。]
2.实例

一个无向图

  • 1
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值