在帶權連通圖 (網圖) 中尋找頂點間權值和最小的路徑。無權圖可視為權值全為 1。
解決單源最短路徑:指定源點到所有其他頂點的最短路徑。要求邊權值非負。
#define MAXVEX 9
#define INFINITY 65535
typedef int PathMatrix[MAXVEX];
typedef int ShortPathTable[MAXVEX];
void ShortestPath_Dijkstra(MGraph G, int v0, PathMatrix *P, ShortPathTable *D) {
int v, w, k, min;
int final[MAXVEX] = {0};
for (v = 0; v < G.numVertexes; v++) {
final[v] = 0;
(*D)[v] = G.arc[v0][v];
(*P)[v] = 0;
}
(*D)[v0] = 0;
final[v0] = 1;
for (v = 1; v < G.numVertexes; v++) {
min = INFINITY;
for (w = 0; w < G.numVertexes; w++)
if (!final[w] && (*D)[w] < min) {
k = w;
min = (*D)[w];
}
final[k] = 1;
for (w = 0; w < G.numVertexes; w++)
if (!final[w] && (min + G.arc[k][w] < (*D)[w])) {
(*D)[w] = min + G.arc[k][w];
(*P)[w] = k;
}
}
}
void PrintPath(PathMatrix P, int v0, int v) {
int path[MAXVEX], top = 0;
int cur = v;
while (cur != v0) {
path[top++] = cur;
cur = P[cur];
}
path[top++] = v0;
while (top--) printf("%d ", path[top]);
}
解決多源最短路徑:任意頂點對之間的最短路徑。允許負權邊,但不允許負權環。
#define MAXVEX 100
typedef int PathMatrix[MAXVEX][MAXVEX];
typedef int ShortPathTable[MAXVEX][MAXVEX];
void ShortestPath_Floyd(MGraph G, PathMatrix *P, ShortPathTable *D) {
int v, w, k;
// 初始化
for (v = 0; v < G.numVertexes; v++)
for (w = 0; w < G.numVertexes; w++) {
(*D)[v][w] = G.arc[v][w];
(*P)[v][w] = w;
}
// Floyd 核心三層迴圈
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]) {
(*D)[v][w] = (*D)[v][k] + (*D)[k][w];
(*P)[v][w] = (*P)[v][k];
}
}
void PrintPath_Floyd(PathMatrix P, int u, int v) {
printf("%d ", u);
while (u != v) {
u = P[u][v];
printf("-> %d ", u);
}
}
| 需求 | 推薦演算法 | 時間複雜度 | 限制條件 |
|---|---|---|---|
| 單源最短路徑 | Dijkstra | O(n²) / O(e log n) 堆優化 | 邊權非負 |
| 單源、有負權邊 | Bellman-Ford | O(n·e) | 無負權環 |
| 多源最短路徑 | Floyd | O(n³) | 無負權環 |
| 稀疏圖多源 | Johnson (Dijkstra + Bellman-Ford) | O(n·e log n) | 無負權環 |