BFS算法
适用性
- 只适用于无权图, 或者是所有边的权值都相同的图
Dijkstra算法
步骤
- 初始化: 集合S初始为{0}, dist[]的初始值为dist[i]=arcs[0][i]
- 从顶点集合V-S中选出vj, 满足dist[j]=Min{dist[i]|vi∈V-S}, vj就是当前求得的一条从v0出发的最短路径的终点, 令S=S∪{j}
- 修改从v0出发到集合V-S上任一顶点vk可达的最短路径的长度: 若dist[j]+arcs[j][k]<dist[k], 则更新dist[k]=dist[j]+arcs[j][k]
- 重复2、3操作共n-1次, 知道所有顶点都包含在S中
两个辅助数组
- dist[]: 记录从原点v0到其他各点的当前的最短路径长度. 初态是: 如果从v0到vj有弧, 则dist[i]为弧上的权值; 否则dist[i]为∞
- path[]: path[i]表示从原点到顶点i之间的最短路径的前驱结点. 当完成该算法后, 可以根据该数组追溯得到v0到vj的最短路径
本质
- 基于贪心策略
复杂度
- 时间复杂度
- 总共2、3步要循环n-1次, 时间复杂度为O(|V|)
- 循环遍历所有的顶点, 找到dist最小且在V-S中的顶点(即步骤2), 时间复杂度为O(|V|)
- 检查所有V-S中除dist值最小的顶点, 按照步骤3更新其最短路径的长度, 时间复杂度为O(|V|)
- 综上所述, 该算法的时间复杂度为O(|V|)*[O(|V|)+O(|V|)]=O(|V|^2)
缺陷
- 无法求解边上带有负权值的最短路径长度
Floyd算法
步骤
- 初始化: 方阵A^(-1)[i][j]=arcs[i][j]
- 将vk作为中间顶点, 对于所有的顶点对{i, j}, 如果有A(m-1)[i][j]>A(m-1)[i][k]+A^(m-1)[k][j], 则将A(m-1)[i][j]更新为A(m-1)[i][k]+A^(m-1)[k][j], 更新后的方阵记为A^(m)
- 重复2的操作, 经过n次的迭代以后, 所得到的A^(m-1)[i][j]就是vi到vj的最短路径长度
复杂度分析
- 时间复杂度
- 以i作为中转结点, 时间复杂度为O(|V|)
- 遍历矩阵, 时间复杂度为O(|V|^2)
- 综上所述, 时间复杂度为O(|V|)*O(|V|2)=O(|V|3)
缺陷
- 允许带有负权值的边, 但是不允许有包含负权值的边组成的回路
本质
- 动态规划思想
- 子问题的最优解构成整体的最优解(无需考虑两个或者多个中转结点的情况)
求解方法
单源最短路径
- BFS算法(无权图)
- Dijkstra算法(带权图、无权图)
各顶点间的最短路径
- Floyd算法(带权图、无权图)