前面在介紹並查集時順便提了kruskal演算法,既然已經說到了最小生成樹問題,就沒有道理不把prime演算法說了。
這裡面先補充下kruskal演算法的大概意思,kruskal演算法通過把所有的邊從小到大排列後,不斷取權值最小的邊加入最小生成樹(起初可能是離散的多個樹,最終連成乙個整體),並通過並查集來捨棄形成迴路的邊。
prime演算法有所不同,prime演算法先將乙個起點加入最小生成樹,之後不斷尋找與最小生成樹相連的邊權最小的邊能通向的點,並將其加入最小生成樹,是一種更符合人的主觀直覺的最小生成樹演算法。
需要注意的是,kruskal和prime都僅適用於無向圖。
#include constint max_v = 100
;const
int inf = 1000000
;int cost[max_v][max_v];//
圖int
v;bool path[max_v][max_v];//
記錄結果
intres;
bool used[max_v];//
表示是否訪問過
int mincost[max_v];//
表示到此點消耗值
void
prime()
}mincost[
0] = 0;//
從0點開始
int prev = 0;//
記錄路徑
while (true
)
if (visited == -1) break
; used[visited] = true
;
if(visited)
res +=mincost[visited];
for (int i = 0;i < v;++i)
}}
下面給出一組kruskal和prime的測試資料及結果:
測試**:
voidmsttest()
for (int i = 0;i < v;++i) d[i] =inf;
cout
<< "
kruskal:
"
for (int i = 0;i < v;++i)
}cout
<< res
<< "
prime
"
for (int i = 0;i < v;++i)
}cout
<< res <}
測試結果:
91000000 1 5 7 4 1000000 1000000 1000000 1000000
1 1000000 1000000 1000000 1000000 3 10 1000000 1000000
5 1000000 1000000 1000000 1000000 2 1000000 2 1000000
7 1000000 1000000 1000000 1000000 1000000 1 1000000 1000000
4 1000000 1000000 1000000 1000000 1000000 1000000 3 1000000
1000000 3 2 1000000 1000000 1000000 1000000 1000000 2
1000000 10 1000000 1 1000000 1000000 1000000 1000000 9
1000000 1000000 2 1000000 3 1000000 1000000 1000000 5
1000000 1000000 1000000 1000000 1000000 2 9 5 1000000
kruskal:
0 10 3
1 52 5
2 73 6
4 75 8
21prime
0 11 5
2 73 6
4 35 2
7 88 4
21請按任意鍵繼續. . .
可以看到,兩種演算法生成了擁有相同最小消耗的兩顆完全不同的最小生成樹。
Prime演算法和Kruskal演算法
利姆 prime 演算法 只與頂點相關 演算法描述 普利姆演算法求最小生成樹時候,和邊數無關,只和定點的數量相關,所以適合求稠密網的最小生成樹,時間複雜度為o n n 演算法過程 1.將乙個圖的頂點分為兩部分,一部分是最小生成樹中的結點 a集合 另一部分是未處理的結點 b集合 2.首先選擇乙個結點,...
普利姆(Prime)演算法
普利姆 prime 演算法 只與頂點相關 演算法描述 普利姆演算法求最小生成樹時候,和邊數無關,只和定點的數量相關,所以適合求稠密網的最小生成樹,時間複雜度為o n n 演算法過程 1.將乙個圖的頂點分為兩部分,一部分是最小生成樹中的結點 a集合 另一部分是未處理的結點 b集合 2.首先選擇乙個結點...
最小生成樹 Prime演算法
對於乙個圖,它的所有生成樹中必有乙個 邊的權值最小 的生成樹,我們把它稱為最小生成樹。概念很抽象,換做實際問題 有十個城市,各個城市之間距離或遠或近。需要建設乙個道路網,把十個城市連線在一起,要求道路網的道路長度最小。各個城市的連線可以抽象為乙個圖,本質上即是求該圖的乙個最小生成樹。每乙個圖可能有多...