最小生成树--Kruskal
文章目录
- 最小生成树的概念
- kruskal的算法思想
- kruskal的代码实现
- kruskal的代码分析
最小生成树的概念
再将最小生成树前,我们需要知道什么是生成树,生成树即在无向图中的最小连通子图。那么最小生成树呢,就是该子图的权值和最小时的生成树。
性质:有n个顶点的连通图的生成树有n个顶点和n-1条边。
kruskal的算法思想
那么我们要怎么实现这个算法呢,我们可以根据贪心的思想,每次取边权最小的一条边,给它加入生成树中,那么n-1次后,就能构成最小生成树了。那么怎么加入生成树中呢?我们这里可以运用并查集,如果边的祖先相同则说明边已经在生成树中,不同则可以把它加入生成树。
kruskal的代码实现
#include<iostream>
#include<algorithm>
using namespace std;
//带权无向图
typedef struct node {
int u, v;
int w;
}Enode;
int n, m;
Enode e[5005];
int f[105];
int find(int x) {
if (x == f[x]) {
return x;
}
return f[x] = find(f[x]);
}
int sum;
void kruskal() {
for (int i = 1;i <= n;i++) {
f[i] = i;
}
for (int i = 1;i <= m;i++) {
int x = e[i].u;
int y = e[i].v;
int f1 = find(x);
int f2 = find(y);
if (f1 != f2) {
f[f1] = f2;
sum += e[i].w;
}
}
}
bool cmp(node a,node b) {
return a.w < b.w;
}
int main() {
cin >> n >> m;
int x, y, w;
for (int i = 1;i <= m;i++) {
cin >> x >> y >> w;
e[i].u = x;
e[i].v = y;
e[i].w = w;
}
sort(e + 1, e + 1 + m, cmp);
kruskal();
cout << sum;
return 0;
}
kruskal的代码分析
我们使用kruskal算法使用的是边集数组,其原因是便于排序以及容易实现。而kruskal算法的时间复杂度也是取决于它的排序算法,为 nlogn 。最后把每次边的权值相加就可以算出最小生成树的权值和了。