最小生成樹算法
#include <stdio.h> #include <string.h> #define INFINITY 1000000 // 無窮大 #define MAX_VERTEX_COUNT 6 // 圖最多頂點數 // 圖的鄰接矩陣 typedef int Graph[MAX_VERTEX_COUNT][MAX_VERTEX_COUNT]; /************************************************************************/ /* 功能:用Prim算法實現構造最小生成樹 /* 參數:g--圖 /* vertexCount -- 圖的頂點數 /* father -- 記錄頂點的雙親 /************************************************************************/ void Prim(Graph g, int vertexCount, int father[]) { int i, j, k; int lowCost[MAX_VERTEX_COUNT]; // 記錄從U到V-U具有最小代價的邊 int closeSet[MAX_VERTEX_COUNT];// 記錄了該邊依附的在U中的頂點,v屬於V-U int used[MAX_VERTEX_COUNT]; // 記錄頂點是否已經被選中放入到U集合中 int min; // 這裏初始選中頂點為1號頂點,這是可以修改的,本程序以1號頂點為默認 for (i = 0; i < vertexCount; i++) { // 最短距離初始化為其他節點到1號節點的距離 lowCost[i] = g[0][i]; // 標記所有節點的依附點皆為默認的1號節點 closeSet[i] = 0; // 所有頂點均未被選中到U集合中 used[i] = 0; // U集合中還沒有頂點,所有值設為-1,表示無雙親 father[i] = -1; } used[0] = 1; // 1號頂點選中,並加入到集合U中 // 依次選取剩餘頂點加入到集合中 for (i = 1; i < vertexCount; i++) { j = 0; min = INFINITY; // 找滿足條件的最小權值邊的頂點k及其編號 for (k = 1; k < vertexCount; k++) { // 邊權值較小且不在生成樹中 if (!used[k] && lowCost[k] < min) { min = lowCost[k]; // 選中頂點 j = k; } } father[j] = closeSet[j]; // 記錄j號頂點的雙親 used[j] = 1; // 將j號頂點選入到生成樹中 // 打印邊即打印該邊連接的兩個頂點(權值最小) printf("%d %d\n",j + 1,closeSet[j] + 1); for (k = 1; k < vertexCount; k++) { // 繼續找邊權值更小的頂點 if (!used[k] && g[j][k] < lowCost[k]) { lowCost[k] = g[j][k]; // 更新最小權值 closeSet[k] = j; // 記錄新的依附點 } } } } int main() { int i, j, weight; Graph g; int father[MAX_VERTEX_COUNT]; int vertexCount; for (i = 0; i < MAX_VERTEX_COUNT; i++) { for (j = 0; j < MAX_VERTEX_COUNT; j++) { g[i][j] = INFINITY; } } // 構造圖 while (scanf("%d%d%d", &i, &j, &weight) != EOF) { // 無向圖是對稱的 g[i - 1][j - 1] = weight; g[j - 1][i - 1] = weight; } Prim(g, 6, father); return 0; }
最後更新:2017-04-03 18:52:05