发现很多东西不记下来过一段时间就想不明白了,先整理一部分,嗯不对的地方请路过的同学指正~
首先,最短路径相关算法通常依赖一个重要性质,即最短路径的子路径也是最短路。证明如下:
单源最短路:
1、Bellman-Fold算法 (将权值变为相反数,可以求最长路)
数组dis[i]]记录从源点s到顶点i的路径长度,初始化数组dis[i]为正无穷, dis[s]为0;
以下操作循环执行至多n-1次,n为顶点数:
这是因为最短路从1到n,最多经过n-1条边,而最上边每一层for循环,实际上是求从源点出发,只经过k条边最短路是多少,k最多n-1
对于每一条边e(u, v),如果dis[u] + w(u, v) < dis[v],则另dis[v] = dis[u]+w(u, v)。w(u, v)为边e(u,v)的权值;
若上述操作没有对Distant进行更新,说明最短路径已经查找完毕,或者部分点不可达,跳出循环(用flag标记优化)。否则执行下次循环;
为了检测图中是否存在负环路,即权值之和小于0的环路。对于每一条边e(u, v),如果存在dis[u] + w(u, v) < dis[v]的边,则图中存在负环路,即是说改图无法求出单源最短路径。否则数组dis[n]中记录的就是源点s到各顶点的最短路径长度。
复杂度为O(VE),最短路可以处理负环。
2、DAG(有向无环图) Shortest Path (可以求最长路)