Kruskal算法构造最小生成树
1.问题
给定一张边带权的无向图G = (V,E) , n =|V| , m = |E| 。由V中全部n个顶点和E中n-1条边构成的无向连通子图被称为G的一棵生成树。边的权值之和最小的生成树被称为无向图G的最小生成树。
2.解析
3.设计
void kruskal(){
sort(edge,edge+m,cmp);//将边的权值排序
for(i from 0 to m-1){
eu=find(edge[i].u);
ev=find(edge[i].v);
if(eu==ev){
//若出现两个点已经联通了,则说明这一条边不需要了
continue;
}
ans+=edge[i].w;//将此边权计入答案
fa[ev]=eu;//将eu、ev合并
if(++cnt==n-1){
//循环结束条件,即边数为点数减一时
break;
}
}
}
4.分析
时间复杂度分析:设n个顶点,m条边。
- 对集合中的每一个顶点,都将它的集合初始化为自身:O(n)
- 将边按权值进行排序:O(mlogm)
- 对排序好后的边从小到大进行判断,如果这条边所连的2个顶点不在同一个集合中,则将这条边加入到生成树的边集A中,并将此边所连的两个顶点u和v的集合放进同一集合中,如此循环加到生成树中的边集数量为n-1时停止。
虽然不确定第三步骤的时间复杂度,但可以肯定的是第三步骤的时间复杂度一定小于O(mlogm),所以综上所诉,Kruskal算法的时间复杂度为O(mlogm)。