Kruskal算法:用來求解最小生成樹的算法,同樣使用貪心思想,只不過是邊的權值最小來貪心。
Prim算法和Kruskal算法都是求解最小生成樹的算法
只是Prim算法在執行時,是枚舉圖中所有結點,故比較適用稠密圖(即結點少,邊多),而Kruskal算法在執行時,是枚舉所有邊,故比較適用稀疏圖(即結點多,邊數少)。
Kruskal算法:
1、構造結構體,裏面存放邊的起始結點,終止結點,邊的權值。
struct edge{
int start;//起始結點
int end;//終止結點
int weight;//邊的權值
};
2、將邊按照從小到大排序。
3、枚舉所有邊,若邊的起始結點和終止結點不在一個集合中。則合併兩個結點,然後把當前的邊加入到最小生成樹中,並更新最小生成樹的總的邊權。
4、重複上述過程,直到最小生成樹的中有 n - 1 條邊,n爲結點數,退出循環。
5、檢查最小生成樹的邊的條數是否爲 n - 1,若不是,則表示該圖爲非連通圖,返回-1,否則返回最小生成樹總的邊權。
樣例:
輸入:
6 10//6個頂點,10條邊。以下10行爲10條邊
0 1 4//邊0->1與1->0的邊權爲4,下同
0 4 1
0 5 2
1 2 1
1 5 3
2 3 6
2 5 5
3 4 5
3 5 4
4 5 3
輸出:
11
解題思路;
使用並查集來表示兩個結點是否在一個集合中,若不在,就合併(這是並查集的方法)
若並查集不是很清楚的,可以看 算法筆記—並查集 這部分。
下面爲實現代碼:
#include<iostream>
#include<algorithm>
using namespace std;
const int max_v = 110;//點的最大值
const int max_e = 10010;//邊的最大值
struct edge
{
int start;//起始結點
int end;//終止結點
int weight;//兩結點之間的邊
}E[max_e];//表示最多有max_e 條邊
bool cmp(edge e1,edge e2){
return e1.weight < e2.weight;
}
int father[max_v];//並查集數組
/**
* @description: 查找當前結點的父結點
* @param : 要查找的結點
* @return: 返回x的根結點
*/
int find_father(int x){
int temp = x;//暫時存放需要查詢的結點
while (x != father[x])
{
x = father[x];
}
//此時 temp 的根結點爲 x
//下面爲路徑壓縮
while (temp != father[temp])
{
int z = temp;
temp = father[temp];
father[z] = x;
}
return x;
}
/**
* @description: kruskal算法
* @param : n 表示結點數; m 表示邊數
* @return: 返回最小生成樹的邊權之和
*/
int kruskal(int n,int m){
int result = 0;//最小生成樹的邊權之和
int edge_num = 0;//表示當前最小生成樹的邊數
//初始化father數組
for(int i = 0;i < n;i++){
father[i] = i;
}
sort(E,E + m,cmp);//將邊的權值按照從小到大的順序排列
//枚舉所有的邊
for(int i = 0;i < m;i++){
int start_father = find_father(E[i].start);
int end_father = find_father(E[i].end);
if(start_father != end_father){
father[start_father] = end_father;//合併集合
result += E[i].weight;
edge_num++;
if(edge_num == n - 1){
//邊數等於結點數 - 1 即已經爲最小生成樹邊的最大值
break;
}
}
}
if(edge_num != n - 1){
//表示給定的圖不是連通圖
return -1;
}
return result;
}
int main(){
int n,m;
cin >> n >> m;
for(int i = 0; i < m; i++){
cin>>E[i].start>>E[i].end>>E[i].weight;
}
int result = kruskal(n,m);
cout<<result<<endl;
system("pause");
return 0;
}
運行結果: