1.问题
举一个实例,画出采用Kruskal算法构造最小生成树的过程。
2.解析
已知图V = {…} 我们构造一棵最小生成树T
第一步:随意选取起点
第二步:将所有边按权值从小到大的顺序排序
第三步:按顺序遍历每条边(不能构成回路),直到所有节点都被遍历了。
实例:
图V如下图所示
①
将每条边按权值从小到大进行排序:
AB BC AD BD DE CE(3 3 4 5 6 7)
选取AB(3)
此时被选中的点:A B
②
接下来是BC(3)
此时被选中的点:A B C
③
接下来是AD(4)
此时被选中的点:A B C D
④
最后是DE(6),虽然BD(5)<DE(6),但是BD会与已经遍历过的点构成回路。
3.设计
void init()//初始化
{
for (int i=0;i<n;++i)parent[i]=i;
}
int find(int x)//查找父亲节点
{
return x==parent[x]?x:find(parent[x]);
}
void Union(int x,int y)//合并
{
int fx=find(x);
int fy=find(y);
parent[fx]=fy;
}
int kruskal(){
sort(e,e+m);
init();
int cnt =0,res=0;
for (int i=0;i<m;++i){
if(find(e[i].u)!=find(e[i].v)){
Union(e[i].u,e[i].v);
res+=e[i].w;
cnt++;
}
if(cnt>n-1)break;
}
return res;
}