这篇文档现在对你可能没用,等你学久了算法就有用了。
众人可能没学过MST只是点进来刷一刷,或者来找关于Kruskal的资料……
那么开始讲吧。
①MST是什么东西?(会图论的散客看)
MST(Mininum Spanning Tree)最小生成树的定义——————
首先我们放一张图(不是图片!自己去查吧),我们假设这张无向图有N个节点,M条边,每条边都有权值。最小生成树,就是选择M条边中的N-1条边,并且要求N-1条边的权值和最小。
你可能会认为这挺难的,其实并不难!
最小生成树有2种(不确定全不全)解决方式:
Kruskal(克鲁斯卡尔)
Prim(普利姆)
由于我Prim掌握还没太全面
就给大家介绍Kruskal吧
②Kruskal的实现方式(会并查集和图论的看)
并查集有一个ancestor数组,ancestor[i]代表结点i的祖先是谁。
解决方案:
①祖先初始化
ancestor[i]=i(i=1~节点编号)
②自定义排序
最好定义结构体typedef,代码如下:
int w;//权值名称
int u,v;//边连接的两个顶点。
bool operator < (const struct 自定义类型名 &t) const
{
return w<t.w;
}
边用自定义类型存放在数组里,按照sort直接排序,不用动。
③循环内容
循环定义:
for(i=0,j=0;i<n-1;++i)//i表示目前的边数量,j是目前选择的边的编号。
{
1.使用find_ancestor自定义函数判断arr[j].左顶点和arr[j].右顶点是否属于一个集合并且当前边数j<m(m是边的数量),如果为真,则j++,否则离开循环//while(find_ancestor(arr[j].u)==find_ancestor(arr[j].v)&&j<m) ++j;
2.1 如果j=m,说明没有边满足,函数直接return 0;
2.2 s+=arr[j].w;//全局变量加上边上的权值。
2.3 j++;//这条边选走了
3.使用union_set自定义函数将arr[j].u和arr[j].v合并至同一个集合。
}
这就是所有的了!
这是Kruskal裸代码。
点个赞吧
再见
754

被折叠的 条评论
为什么被折叠?



