单源最短路径Dijkstra算法,多源最短路径Floyd算法
1.单源最短路径
(1)无权图的单源最短路径
1 /*无权单源最短路径*/ 2 void UnWeighted(LGraph Graph, Vertex S) 3 { 4 std::queue<Vertex> Q; 5 Vertex V; 6 PtrToAdjVNode W; 7 Q.push(S); 8 while (!Q.empty()) 9 { 10 V = Q.front(); 11 Q.pop(); 12 for (W = Graph->G[V].FirstEdge; W; W = W->Next) 13 if (dist[W->AdjV] != -1) 14 { 15 dist[W->AdjV] += dist[V] + 1; 16 path[W->AdjV] = V; 17 Q.push(W->AdjV); 18 } 19 20 } 21 22 }
函数:返回还未被收录顶点中dist最小者
1 Vertex FindMinDist(MGraph Graph, int dist[], int collected[]) 2 { 3 /*返回未被收录顶点中dist最小者*/ 4 Vertex MinV, V; 5 int MinDist = INFINITY; 6 7 8 for (V = 0; V < Graph->Nv; ++V) 9 { 10 if (collected[V] == false && dist[V] < MinDist) 11 { 12 MinDist = dist[V]; 13 MinV = V; //更新对应顶点 14 } 15 } 16 if (MinDist < INFINITY) //若找到最小值 17 return MinV; 18 else 19 return -1; 20 }
(2)有权图的单源最短路径
单源最短路径Dijkstra算法
1 /*单源最短路径Dijkstra算法*/ 2 /*dist数组存储起点到这个顶点的最小路径长度*/ 3 bool Dijkstra(MGraph Graph, int dist[], int path[], Vertex S) 4 { 5 int collected[MaxVertexNum]; 6 Vertex V, W; 7 8 /*初始化,此处默认邻接矩阵中不存在的边用INFINITY表示*/ 9 for (V = 0; V < Graph->Nv; V++) 10 { 11 dist[V] = Graph->G[S][V]; //用S顶点对应的行向量分别初始化dist数组 12 if (dist[V] < INFINITY) //如果(S, V)这条边存在 13 path[V] = S; //将V顶点的父节点初始化为S 14 else 15 path[V] = -1; //否则初始化为-1 16 collected[V] = false; //false表示这个顶点还未被收入集合 17 } 18 19 20 /*现将起点S收录集合*/ 21 dist[S] = 0; //S到S的路径长度为0 22 collected[S] = true; 23 24 while (1) 25 { 26 V = FindMinDist(Graph, dist, collected); //V=未被收录顶点中dist最小者 27 if (V == -1) //如果这样的V不存在 28 break; 29 collected[V] = true; //将V收录进集合 30 for (W = 0; W < Graph->Nv; W++) //对V的每个邻接点 31 { 32 /*如果W是V的邻接点且未被收录*/ 33 if (collected[W] == false && Graph->G[V][W] < INFINITY) 34 { 35 if (Graph->G[V][W] < 0) //若有负边,不能正常解决,返回错误标记 36 return false ; 37 if (dist[W] > dist[V] + Graph->G[V][W]) 38 { 39 dist[W] = dist[V] + Graph->G[V][W]; //更新dist[W] 40 path[W] = V; //更新S到W的路径 41 } 42 } 43 } 44 } 45 return true; 46 }
2.多源最短路径Floyd算法
1 /*多源最短路径*/ 2 bool Floyd(MGraph Graph, WeightType D[][MaxVertexNum], Vertex path[][MaxVertexNum]) 3 { 4 Vertex i, j, k; 5 6 /*初始化*/ 7 for (i = 0; i < Graph->Nv; i++) 8 for (j = 0; j < Graph->Nv; j++) 9 { 10 D[i][j] = Graph->G[i][j]; 11 path[i][j] = -1; 12 } 13 14 for (k = 0; k < Graph->Nv; k++) 15 for (i = 0; i < Graph->Nv; i++) 16 for (j = 0; j < Graph->Nv; j++) 17 { 18 if (D[i][k] + D[k][j] < D[i][j]) 19 D[i][j] = D[i][k] + D[k][j]; 20 if (i == j && D[i][j] < 0) //若发现负值圈,不能正常解决,返回错误标记 21 return false; 22 path[i][j] = k; 23 } 24 return true; //算法执行完毕,返回正确标记 25 }