繁体   English   中英

如何使用联合查找,最小堆,克鲁斯卡尔算法和排序算法来创建最小成本生成树? (C ++)

[英]How to use union-find, minheap, Kruskal's, and a sort algorithm to create a minimum cost spanning tree? (C++)

如果这个问题有点宽泛,我深表歉意,但是我很难理解我将如何创建最小成本生成树。 如果有关系的话,这就是C ++。

据我了解,您将使用Kruskal选择构建生成树的最小成本边。 我的想法是将边缘读入minheap中,这样就可以从顶部移除边缘,从而以最小的成本获得边缘。

到目前为止,我只能够实现最小堆和集合以进行联合查找,但是我仍然不确定联合查找的目的以及用于创建生成树的排序算法。

我将不胜感激任何建议。

编辑:我不仅限于联合查找,minheap,kruskals和排序算法,也不需要执行任何操作。 这些只是讲师建议的项目。

这两种结构在算法中具有不同的用途。 Kruskal的算法通过在不形成循环的每个点上添加尽可能便宜的边来工作。 可以使用一些不是特别复杂的数学来证明,这可以保证生成的生成树最小。 为何起作用的直觉如下。 假设Kruskal的算法不是最佳算法,并且存在便宜的生成树。 按权重对树中的所有边缘进行排序,然后将这些边缘按排序顺序与Kruskal算法选择的边缘按排序顺序进行比较。 由于我们假设Kruskal算法不是最优的,因此必须在序列中的某些地方存在分歧。 如果在这种分歧中,Kruskal算法的边缘比最佳解决方案要轻,那么我们可以通过添加该边缘,找到它创建的周期,然后删除周期中最重的边缘,来使最佳解决方案更好。 该边缘不能是我们刚刚添加的边缘,因为否则会在Kruskal算法产生的MST中创建一个循环,而Kruskal算法从不添加创建循环的边缘。 因此,这意味着Kruskal的算法必须通过不增加一些亮边而偏离了最佳解决方案。 但是Kruskal算法跳过边缘的唯一原因是如果它创建了一个循环,这意味着最优MST中必须存在一个循环,这也是一个矛盾。 这意味着我们的假设是错误的,并且Kruskal的算法必须是最优的。

希望这激发了为什么Kruskal算法需要堆和联合查找结构。 我们需要堆,以便可以按排序顺序返回所有边缘。 如果我们不按此顺序访问边缘,则上述证明会失效,所有赌注都将关闭。 有趣的是,您实际上并不需要堆。 您只需要某种方式即可按排序顺序访问所有边缘。 如果需要,您可以将所有边都转储到一个巨大的数组中,然后对数组进行排序。 如果使用快速排序,这不会改变二进制堆情况下算法的运行时间。

工会发现的结构有些棘手。 在Kruskal算法的每个点上,您都需要能够判断添加一条边是否会在图形中创建一个循环。 一种实现方法是存储一种结构,该结构跟踪哪些节点已经相互连接。 这样,在添加边缘时,可以检查端点是否已连接。 如果是这样,则边缘将形成一个循环,应忽略。 联合查找结构是有效维护此信息的一种方式。 特别是,它的两个操作(union和find)对应于将以前未连接的两个不同的节点组连接在一起的行为,如果添加一条连接连接跨区不同部分中的两棵树的边的情况就是这种情况。森林。 查找步骤为您提供了一种检查两个节点是否已连接的方法。 如果是这样,您应该跳过当前边缘。

希望这可以帮助!

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM