青岛oj集训4
Dijkstra算法——单源最短路
- 算法流程(O(m+n^2))
1)把dis[1(起点)]=0,dis[……]=inf
2)从一号点向每条出边做松弛,更新dis,把1打标记
3)从未被打标记的点中选出dis最小的点,向所有临边(未被打标记)做松弛,更新dis(共执行n轮)
(性质:当一个点被打上标记时,最终最短路已经被完全确定)
(证明:因为这个点必须要是当时dis最小的点,那么任何其他点的dis+正边权就要大于这个点的dis)
(所以dijk只能在正权图里跑)
2.优化(O(m log m))->如果遇到稠密图,m变成n^2级别,会比不优化还慢
每一轮都要暴力枚举每个点以找到最小的点,太暴力
所以要快速维护出未被标记且dis最小的点
所以要使用优先队列
使用大根堆倒着存(小根堆也行)
由于代码用的是vector存图,然后还要存点和边权
所以vector开的是一个node(struct)类型
但是无论大根堆还是小根堆都要用到小于号
小于号没法比较你自己定义的struct的
所以要对小于号进行重定义,即让它变成比较两个node相比较
所以要在struct里面进行重定义
看下面的代码,可以翻译成中文:
如果一个node小于另一个名为a的node(你要是写成名为a的int也行,不过这题要用大根堆,小于号比较的两端都是node),代表的含义是:
这个node的len参数要大于a的len参数。
为啥是大于呢?
首先这里是大根堆反着用
大根堆会把优先级高的数放在前面
大根堆有个反常性质:如果一个数小于另一个数,那么它会认为后边的优先级更高(更小)
所以一个node小于另一个名为a的node,就是一个node优先级低于a
他以为a更大,因为a的优先级更高
所以他会把a往上放
我们不这样想啊,我们想把len小的往上放
所以当a往上放时,我们希望a.len更小
所以代表的含义是:
这个node的len参数要大于a的len参数。


3.次短路与k短路
记录dis[i][j],表示i点的第j+1短的路径
更新到一个新的路径值

本文来自博客园,作者:永韶,转载请注明原文链接:https://www.cnblogs.com/yongshao/p/18792519

浙公网安备 33010602011771号