一、各种名词:
(1)负权回路。
负权回路是指如果一个环的总长度为负数,那么就叫做负权回路
(2)重边。
重边是指a->b这条边会有两次及以上的输入(是同向的)
(3)自环。
自环是指a->a的距离(即自己到自己)
二、最短路算法:
(1)朴素Dijkstra算法:复杂度
Dijkstra只能用于求解正边权的最短路,其时间复杂度只与点数有关;一般用于求解稠密图的最短路
(2)堆优化Dijkstra算法:复杂度
堆优化的Dijkstra,其时间复杂度既与点数有关,也与边数有关;一般用于求解稀疏图的最短路
(3)bellman-ford算法:复杂度
bellman-ford用于求解有负权边的最短路问题,并且可以规定起点到终点之间最多经过几条边,还可以用于判断负环(负权回路)
(4)spfa算法:复杂度
spfa也是用于求解有负权边的最短路问题,其实质上是bellman-ford的队列优化版本,而且一般判断负环时用spfa而不是bellman-ford
(5)floyd算法:复杂度
floyd一般用于求解多源汇最短路问题,它既可以处理正权边,也可以处理负权边,但是不能处理负权回路
三、各种注意事项:
(1)对于重边,用邻接表存图的话不用做特殊处理,但是用邻接矩阵存图的话,就要取最小值
(2)对于自环,邻接表和邻接矩阵都不用做特殊处理,因为在取min的时候自环必然不会被选择
(3)对于floyd,自己到自己(自环)的距离要初始化为0,但是Dijkstra就不需要。因为在floyd的状态更新中,g[i][j]=min(g[i][j],g[i][k]+g[k][j]),三层循环遍历可能会出现i==k的情况;但是对于Dijkstra的更新,dist[j]=min(dist[j],dist[t]+w[i]),如果j==t,并且边权为正,那么肯定是dis[t]最小。
(4)如果有负权回路,并不说明在求解最短路的过程中一定会死循环,只是说理论上最短路是负无穷,但是我们求出来的值只是一个确定的数