【演算法思想】:演算法對權值從小到大排序,每次選取當前權值最小的邊加入結點,直到所有的結點都已加入結點。演算法中用到了並查集的思想(並查集),通過並查集來判斷兩個結點是否有共同的父節點,如果有,則表明兩個結點已經聯通。如果沒有,就將兩個結點聯通,記錄路徑。
使用結構體陣列來存圖;
struct node
mp[n]; //定義乙個結構體陣列來存圖;
分為三部分:
(1)初始化:使每個結點的初始根節點為自己,並且每個結點構成一顆樹,樹的深度是1;
(2)查詢:使用遞迴來查詢每個結點的父親結點;
(3)合併:將不同父節點的結點合併;
注:這裡的並查集是優化後的,即:進行了路徑壓縮。如果題目中無要求,可以只寫簡單的並查集演算法。
void inin(int n)
}int find(int x) //找每個結點的父親結點;
}bool join(int a,int b) //將兩個不同父節點的結點合併
else
par[fa] = fb;
} return true;
}
變數每個結點;
int kruskal(int m)
} return sum;
}
kuskal演算法完整**實現:
#include
#include
#include
using namespace std;
#define n 1000
int par[n]
;//記錄父親結點
int rank1[n]
;//樹的深度;
int sum;
//最短路徑
struct node
mp[n]
;//定義乙個結構體陣列來存圖;
bool cmp
(node a,node b)
//對邊的權值進行從小到大排序
void
inin
(int n)
}int
find
(int x)
//找每個結點的父親結點;
}bool join
(int a,
int b)
//將兩個不同父節點的結點合併
else
par[fa]
= fb;
}return true;
}int
kruskal
(int m)
}return sum;
}int
main()
sum =0;
kruskal
(m);
cout << sum << endl;
return0;
}
輸入樣例1:5個點,8條邊,
5 8輸出:1 2 3
1 3 7
2 3 10
2 4 4
2 5 8
3 4 6
3 5 2
4 5 17
輸入樣例2:9個點,14條邊,
9 14輸出:371 2 4
2 3 8
3 4 7
4 5 9
5 6 10
6 7 2
7 8 1
8 9 7
2 8 11
3 9 2
7 9 6
3 6 4
4 6 14
1 8 8
最小生成樹之Kruskal演算法
最小生成樹 kruskal演算法描述 該演算法是基於貪心的思想得到的。首先我們把所有的邊按照權值先從小到大排列,接著按照順序選取每條邊,如果這條邊的兩個端點不屬於同一集合,那麼就將它們合併,直到所有的點都屬於同乙個集合為止。合併頂點可以利用並查集,換而言之,kruskal演算法就是基於並查集的貪心演...
最小生成樹之kruskal演算法
先構造乙個只含 n 個頂點 而邊集為空的子圖,把子圖中各個頂點看成各棵樹上的根結點,之後,從網的邊集 e 中選取一條權值最小的邊,若該條邊的兩個頂點分屬不同的樹,則將其加入子圖,即把兩棵樹合成一棵樹,反之,若該條邊的兩個頂點已落在同一棵樹上,則不可取,而應該取下一條權值最小的邊再試之。依次類推,直到...
最小生成樹之kruskal演算法
克魯斯卡爾 kruskal 演算法過程 構造最小生成樹 u,te 1.置u的初值等於v 即包含有g中的全部頂點 te的初值為空集 即圖t中每乙個頂點都構成乙個連通分量 2.將圖g中的邊按權值從小到大的順序依次選取 若選取的邊未使生成樹t形成迴路,則加入te 否則捨棄,直到te中包含 n 1 條邊為止...