演算法基本思想:
在初始狀態時隱去圖中的所有邊,這樣圖中每個頂點都自成乙個連通塊。之後執行下面的步驟:
(1)對所有的邊按邊權從小到大進行排序;
(2)按邊權從小到大測試所有邊,如果當前測試邊所連線的兩個頂點不在同乙個連通塊中,則把這條測試邊加入當前最小生成樹中;否則,將邊捨棄;
(3)執行步驟(2),知道最小生成樹中的邊數等於總頂點數減1或者測試完所有的邊時結束。當結束時,如果最小生成樹的邊數小於總頂點數減1,則說明該圖不連通。
並查集
(1)如何判斷測試邊的兩個端點是否在不同的連通塊中;
(2)如何將測試邊加入到最小生成樹中;
其實可以把每個連通塊當做乙個集合,判斷兩個端點是否在同乙個連通塊中就可以轉換為判斷兩個端點是否在同乙個集合中,解決這個問題的方法是使用並查集。並查集可以通過查詢兩個結點所在集合的根結點是否相同來判斷它們是否在同乙個集合中,而合併功能恰好可以解決上面提到的第二個問題,即只要把測試邊的兩個端點所在集合合併,就能達到將邊加入最小生成樹的目的。
查:
//返回頂點x的根節點,p為並查集陣列
intfind
(vector<
int>
& p,
int x)
return r;
//將根結點返回
}
並:
int x=
find
(p,e[i]
.u);
//頂點u的根結點
int y=
find
(p,e[i]
.v);
//頂點v的根結點
if(x!=y)
//不屬於同乙個集合,否則會形成迴路
vectorp這個不定陣列(也可以用定長陣列,但vector更方便),記錄了每個結點的父節點是誰。頂點們從1或者0開始編號(依據題意而定),p[15]=3就表示15號頂點的父節點是3號頂點。如果乙個頂點的父節點就是他自己,那說明他就是根結點了,查詢到此為止。 find這個函式就是找根結點用的,意義再清楚不過了。
路徑壓縮演算法
建立樹的過程是將兩個根結點連線起來的,誰當誰的父節點完全隨機。最後的樹狀結構會變成什麼樣,完全無法預計,一字長蛇陣也有可能。這樣查詢的效率就會比較低下。最理想的情況就是所有節點的父節點都是根結點,一共就兩級結構,只要找一次就找到根結點了。哪怕不能完全做到,也最好盡量接近。路徑壓縮的**,看得懂很好,看不懂也沒關係,直接抄上用就行了。總之它所實現的功能就是這麼個意思。
具體**實現:
#include
#include
#include
using namespace std;
struct edge //kruskal演算法是對邊進行遍歷,因此需要對邊的定義。
;//返回頂點x的根節點,p為並查集陣列
intfind
(vector<
int> p,
int x)
return r;
//將根結點返回
}bool compare
(edge a,edge b)
//邊權值比較函式
//kruskal演算法生成最小生成樹,返回其權值和
intkruskal
(int n,
int m,vector
& e)
//n:頂點的個數,m:邊的數目,e:邊集
sort
(e.begin()
,e.end()
,compare)
;//按邊的權值從小到大進行排序
for(
int i=
0;i)//遍歷所有的邊
if(num_edge==n-1)
//最小生成樹的邊數等於n-1,滿足這一條件結束
break;}
if(num_edge//邊的數目小於n-1說明不連通
return-1
;return ans;
}int
main()
);e.
push_back()
; e.
push_back()
; e.
push_back()
; e.
push_back()
; e.
push_back()
; e.
push_back()
; e.
push_back()
; e.
push_back()
; e.
push_back()
;int n =6;
int m =10;
int res =
kruskal
(n, m, e)
; cout << res ;
return0;
}
kruskal演算法的時間複雜度主要**於對邊的排序,因此其時間複雜度為o(nlogn),其中n是圖中邊的數目。該演算法適合頂點數較多,邊數較少的情況。 最小生成樹 Kruskal 克魯斯卡爾 演算法
給定乙個無向圖 頂點間連線不帶方向 如果它任意兩個頂點都聯通並且是一棵樹,那麼我們就稱之為生成樹 spanning tree 如果是帶權值的無向圖,那麼權值之和最小的生成樹,我們就稱之為最小生成樹 mst,minimum spanning tree 最小生成樹廣泛應用於城市間道路建設的優化,通訊網路...
kruskal 最小生成樹
include include 產生隨機數組用 include 同上 include using namespace std 1 帶權邊的類myarc class myarc bool operator const myarc arc myarc myarc int beginvex,int end...
最小生成樹Kruskal
最小生成樹有兩個特點,乙個是保證了所有邊的和是最小值,另乙個是保證了所有邊中的最大值最小。struct edge bool friend operator edge a,edge b 構邊 vectoredge int id max int mini void initial void input ...