SPFA可以处理负权边,但是不能处理有负权回路的图;而Dijkstra不能处理带有负权边和负权回路的图,因为Dijkstra算法在计算最短路径时,不会因为负边的出现而更新已经计算过(收录过)的顶点的路径长度;
总结一下:Bellman-ford可以处理任意带负权边和负权环的图,SPFA可以处理带负权边的图,Dijkstra只能处理带正权边的图;当然,从时间复杂度的效率来讲,是反过来的.
Dijkstra-朴素 O(n2)
初始化距离数组, dist[1] = 0, dist[i] = inf;
for n次循环 每次循环确定一个min加入S集合中,n次之后就得出所有的最短距离
将不在S中dist_min的点->t
t->S加入最短路集合
用t更新到其他点的距离
Dijkstra-堆优化 O(mlogm)
利用邻接表,优先队列
在priority_queue< PII,vector< PII >,greater< PII > > heap;中将返回堆顶
利用堆顶来更新其他点,并加入堆中类似宽搜
Bellman_ford O(nm)
注意连锁想象需要备份, struct Edge{int a,b,c} Edge[M];
初始化dist, 松弛 dist[x.b] = min(dist[x.b], backup[x.a]+x.w);
松弛k次,每次访问m条边
Spfa O(n)∼O(nm)
利用队列优化仅加入修改过的地方
for k次
for 所有边利用宽搜模型去优化bellman_ford算法
更新队列中当前点的所有出边
Floyd O(n3)
初始化d
k, i, j 去更新d