这是我参与8月更文挑战的第13天,活动详情查看:8月更文挑战算法
最短路径与最小生成树不一样,路径上不必定包含n个顶点markdown
把图中顶点集合分红两组:post
第一组为已求出其最短路径的顶点集合S 第二组为还没有肯定最短路径的顶点集合Uspa
算法流程图 C++代码实现code
void ShortestPath_DIJ(AMGraph G, int v0){
// 用Dijkstra算法求有向网G的v0顶点到其他顶点的最短路径
n = G.vexnum; // G 中顶点个数
for(v = 0; v < n; v++){
// n 个顶点依次初始化
S[v] = false; // S 初始为空集
D[v] = G.arcs[v0][v]; // 将v0到各个终点的最短路径长度初始化
if(D[v] < MaxInt) Path[v] = v0; // v0和v之间有弧,将v的前驱置为v0
else Path[v] = -1; // 若是v0和v之间无弧,则将v的前驱置为-1
}
S[v0] = true; // 将v0加入S
D[v0] = 0; // 源点到源点的距离为0
/*―开始主循环,每次求得v0到某个顶点v的最短路径,将v加到S集―*/
for(i = 1; i < n; i++){
// 对其他n-1个顶点,依次进行计算
min = MaxInt;
for(w = 0; w < n; w++)
if(!S[w] && (D[w] < min)){
v = w;
min = D[w]; // 选择一条当前的最短路径,终点为v
}
S[v] = true; // 将v加入S
for(w = 0; w < n; w++) // 更新从v0出发到集合V−S上全部顶点的最短路径长度
if(!S[w] && ((D[v] + G.arcs[v][w]) < D[w])){
D[w] = D[v] + G.arcs[v][w]; // 更新D[w]
Path[w] = v; // 更新w的前驱为v
}
}
}
复制代码
每一对顶点之间的最短路径orm
方法一:每次以一个顶点为源点,重复执行Dijkstra算法n次—— T(n)=O(n³) 方法二:弗洛伊德(Floyd)算法 算法思想:逐个顶点试探法图片
typedef int Pathmatirx[MAXVEX][MAXVEX]
typedef int ShortPathTable[MAXVEX][MAXVEX]
/*- Floyd算法,求网图G中各顶点v到其他顶点w最短路径P[v][w]及带权长度D[v][w] -*/
void ShrotestPath_Floyd(MGraph G, Pathmatirx* P, ShortPathTable* D){
int v, w, k;
for(v = 0; v < G.numVertexes; ++v){
// 初始化D与P
for(w = 0; w < G.numVertexes; ++w){
(*D)[v][w] = G.matirx[v][w]; // D[v][w]值即为对应点间的权值
(*P)[v][w] = w; // 初始化P
}
}
for(k = 0; k < G.numVertexes; ++k)
for(v = 0; v < G.numVertexes; ++v)
for(w = 0; w < G.numVertexes; ++w)
if((*D)[v][w] > (*D)[v][k] + (*D)[k][w]){
// 若是通过下标为k顶点路径比原两点间路径更短
// 将当前两点间权值设为更小的一个
(*D)[v][w] = (*D)[v][k] + (*D)[k][w];
(*P)[v][w] = (*P)[v][k]; // 路径设置为通过下标为k的顶点
}
}
复制代码