最短路径问题
在有向图中A点到B点的多条路径中,寻找一条各边权值之和最小的路径,即最短路径。
单源点最短路径—迪杰斯特拉Dijkstra
- 用带权值的邻接矩阵来表示带权有向图,arcs[i][j]表示弧<vi,vj>上的权值。若<vi,vj>不存在,则置权值为∞
- 选择最小的权值,将该弧弧头并入集合S。
- 修改从v出发到集合V-S上任意一顶点vk可达的最短路径长度。
- 重复上述操作n-1次。
即求得路径长度递增的序列。*
样例解释
代码实现
void ShortestPath_DIJ(MGraph G, int v0, PathMatrix& P, ShortPathTable& D) {
//若P[v][w]为ture,则是从v0顶点到v当前求得最短路径上的顶点。
//final[v]为ture当且仅当v属于S,即已经求得从v0到v的最短路径。
for (v = 0; v < G.vexnum; ++v) {
final[v] = false;
D[v] = G.arcs[v0][v];
//初始化,将与v0相邻的点的权值赋值给D[v]
for (w = 0; w < G.vexnum; ++w) {
P[v][w] = false;//设空路径
}
if (D[v] < infinity) {
P[v][v0] = true;
P[v][v] = true;
}
}
D[v0] = 0; final[v0] = true;
//每次求得v0到某个顶点v的最短路径,并加入v到S集
for (i = 1; i < G.vexnum; ++i) {
min = infinity;
for (w = 0; w < G.vexnum; ++w) {
if (!final[w]) {
if (D[w] < min)
v = w; min = D[w];
}
}
final[v] = true;
//把离v0最近的点加入S集
for (w = 0; w < G.vexnum; ++w) {
if (!final[w] && (min + G.arcs[v][w] < D[w])) {
D[w] = min + G.arcs[v][w];
//更新最短距离
P[w] = P[v];
P[w][w] = true;
}
}
}
}
所有顶点之间的最短路径-弗洛伊德算法
即先存入所有权值,不直接存在的路径设为∞。再依次填入顶点,更新每两顶点之间最短路径,此时路径中可包含新填入结点,直至所有结点都被填入,全部更新完毕,所得结果即为全部最短路径。
样例解释
下面例子即为依次填入A B C 三个结点的更新过程。