城市 = 頂點,道路 = 邊,距離 = 權重。求連接所有城市且總長度最小的方案 → 最小生成樹(MST)。
weight[i] 及對應鄰接點 parent[i]weight 最小的頂點 u 加入 S,累加權重,輸出邊 (parent[u], u)weight[v]:若 edge[u][v] < weight[v] 則更新void Prim(GraphMatrix& G) {
vector<int> weight(G.VertexNum, INF), parent(G.VertexNum, -1);
vector<bool> inMST(G.VertexNum, false);
weight[0] = 0; int total = 0;
for (int i = 0; i < G.VertexNum; ++i) {
int u = -1, minW = INF;
for (int j = 0; j < G.VertexNum; ++j)
if (!inMST[j] && weight[j] < minW) { minW = weight[j]; u = j; }
inMST[u] = true; total += minW;
if (parent[u] != -1) cout << '(' << G.Vertex[parent[u]] << ',' << G.Vertex[u] << ") ";
for (int v = 0; v < G.VertexNum; ++v)
if (!inMST[v] && G.EdgeWeight[u][v] < weight[v]) {
weight[v] = G.EdgeWeight[u][v];
parent[v] = u;
}
}
cout << "\nTotal weight: " << total << '\n';
}
同樣的圖,求指定起點到終點的最短路徑長度及路徑本身。
dist[v] = edge[start][v],path[v] = start(若可達),visited[start] = truedist 最小的 u,標記訪問dist[u] + edge[u][v] < dist[v],更新 dist[v] 和 path[v] = upath 回溯輸出路徑
void Dijkstra(GraphMatrix& G, int start) {
vector<int> dist(G.VertexNum, INF), path(G.VertexNum, -1);
vector<bool> vis(G.VertexNum, false);
for (int i = 0; i < G.VertexNum; ++i) {
if (G.EdgeWeight[start][i] < INF) {
dist[i] = G.EdgeWeight[start][i];
path[i] = start;
}
}
dist[start] = 0; vis[start] = true;
for (int i = 1; i < G.VertexNum; ++i) {
int u = -1, minD = INF;
for (int j = 0; j < G.VertexNum; ++j)
if (!vis[j] && dist[j] < minD) { minD = dist[j]; u = j; }
if (u == -1) break;
vis[u] = true;
for (int v = 0; v < G.VertexNum; ++v)
if (!vis[v] && G.EdgeWeight[u][v] < INF && dist[u] + G.EdgeWeight[u][v] < dist[v]) {
dist[v] = dist[u] + G.EdgeWeight[u][v];
path[v] = u;
}
}
// 輸出路徑...
}
| 問題 | 目標 | 算法 | 輸出 |
|---|---|---|---|
| 最短總距離 | 連通所有城市,總長度最小 | Prim (MST) | 樹的邊集合、總權重 |
| 兩點最短路徑 | 指定起終點間距離最小 | Dijkstra | 路徑頂點序列、距離 |
同一圖模型,不同目標對應不同經典算法。MST 關注全局連通最優,最短路徑關注局部點對點最優。掌握 Prim 與 Dijkstra 的鄰接矩陣實現,是圖論算法入門的必修課。