其实我在学最短路之前就学了生成树了,现在接着写。
本文介绍2种算法:Kruskal,Prim
PS:文中分大小写。 图为G(V,E),V为节点集合,E为边集合,但v表示某个节点(v∈V)
其实很多都和最短路差不多的,松弛操作不同而已。
前提:连通图
Kruskal:
- 原理: 通过排序每一条边(权值递增)从|E|条边中取V-1条边出来(V个点嘛,最小生成树始终是V-1条边的),满足每次选的边的起点和终点不在一棵树上。
- 采用: 并查集
- 步骤:
- 初始化边,并以升序排序
- 初始化并查集,这里以p域代表, p[i]=i; // i∈[1,|V|]
- 循环(1~|E| : i)
1)判断第i条边的起点和终点是否在一棵树上(使用并查集,可保证非常快的判断)
2)如果不在的话,加入i边,并使得p[起点]=终点 或 p[终点]=起点
并查集实现:
inline int find(int x)
{
int t = x;
while(p[x] != x) x = p[x];
p[t] = x;
return x;
}
- 分析:时间复杂度O(E) 并查集的时间太小 省略。</