【圖論】最小生成樹

最小生成樹

生成樹

現在一張有n 個點的聯通無向圖G
G 的一個子圖是一顆包含所有點的樹
則稱這顆樹爲原圖G 的生成樹

簡單來說就是用n1 條邊將所有點連起來,這些邊所形成的便是原圖的生成樹

最小生成樹

如果把每條邊加上邊權,生成樹的n1 條邊的權值之和最小的被稱爲最小生成樹
舉個例子
最小生成樹
其中的藍邊就是該圖的最小生成樹

最小生成樹算法

最常見的有Kruskal和Prim
由於Prim堆優化實在是不如Kruskal來的方便簡單,理解上也是Kruskal容易,所以直介紹Kruskal
Kruskal
生成樹既然是一棵樹,那麼肯定不存在迴路
這樣就可以把邊從小到大排序,之後依次循環往最小生成樹中加邊。
如果加入這條邊後樹中形成迴路,則不加此邊。
若樹中已含有n1 條邊便停止循環,這時的樹就是最小生成樹。
其中判斷迴路可以用並查集來實現。
加入一條邊(u,v)
1. 如果uv 已經在同一個集合之中,便是形成迴路,不加此邊。
2. 否則增加此邊,將u ,v 合併。
主要代碼:

scanf("%d%d", &n, &m);
for(int i = 1; i <= m; i++)
        scanf("%d%d%d", &edge[i].u, &edge[i].v, &edge[i].w);
sort(edge + 1, edge + m + 1);
for(int i = 1; i <= m; i++)
    if(Union(edge[i].u, edge[i].v))
        addedge(edge[i].u, edge[i].v, edge[i].w);
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章