Dijkstra最短路径算法
算法的基本思想是每次找离源点最近的一个点,然后以该点为中心进行扩展,直到|v|-1个点的最短路径都找到。
1. 将所有的点都划分为两部分P和Q,P代表已知最短路径的顶点集合,Q代表未知最短路径的顶点集合,用一个mask数组来表示顶点在哪一个集合,mask[i] = 1表示顶点i在P内,mask[i] = 0表示顶点i在Q内。初始情况下只有源点在P内;
2. 建立dist数组,表示源点到每个顶点的最短路径。初始时,dist[begin] = 0,dist[i] = e[begin][i];
3. 在集合Q中选择一个顶点u使得源点到顶点u的距离最小,将u加入集合P中;以u为中心,选择u的邻接点v,查看是否dist[v]是否大于dist[u] + e[u][v],如果大于的话则更新dist[v];
4. 重复第三步,如果集合Q为空,则算法结束,输出最短路径。
注意:dijkstra算法只能处理带正权重的图,不能处理负权重。
考虑这么一种情况,a->b = 2, a->c = 1, b->c = -2,源点是a,那么按照dijkstra算法,第一步会先将a并入P,然后选择距离P最小的节点,在这里就会选择c,此时c被并入P那么a->c的的最短路径就会被冻结为1,不会再修改,而实际上到c的最短路径等于0.
Bellman-Ford最短路径算法
相较于Dijkstra算法,bellman-Ford的优势在于它可以应用于边的权值为负数的图;贝尔曼算法简单地对所有边进行遍历|v|-1次,并进行松弛,即比较dist[edges[j].from] + edges[j].cost与dist[edges[j].to]的大小。