给定一张G(V,E)加权(在边上)图,我需要找到每个MST中属于的边数,以及至少属于一个但不是全部的边数。不属于任何人。
图形以以下形式(示例)作为输入提供:
3 3
1 2 1
1 3 1
2 3 2
前3个是节点数,后3个是边数。接下来的三行是第一个数是它们的起点,第二个是它们的终点,第三个是值的边缘。
我考虑过一次运行kruskal来找到一个MST,然后针对属于G的每个边缘检查(线性?)时间是否可以替换该MST中的一条边缘而不改变其整体重量。它不属于任何一个,如果它可以属于一个但不是全部,我还可以在第一个MST中标记边缘(可能用第二个值1或0),最后检查不能替换的边缘这些是所有可能的MST中的成员。该算法可能是O(V ^ 2),我不太确定如何用C ++编写它。我的问题是,能否以某种方式降低它的复杂性?如果我在MST上添加一条边,如何检查(并用C ++实现)形成的循环中是否包含权重较小的边?
答案 0 :(得分:0)
您可以通过在Kruskal的算法中添加一些额外的工作来做到这一点。
在Kruskal算法中,具有相同权重的边可以按任意顺序排列,并且实际检查边缘的顺序确定了从所有可能的MST中获得哪个MST。对于每个MST,将产生该树的边都有排序一致的顺序。
无论使用哪种排序一致顺序,权重之间的联合查找结构的状态都将相同。
如果只有一个特定权重的一个边缘,那么如果Kruskal的算法选择了该边缘,则它将出现在每个MST中,因为它将以任何排序一致的边缘顺序进行选择,否则为没有MST。
如果存在多个具有相同权重的边,并且Kruskal的算法将选择其中至少一个,则可以在那一点上暂停Kruskal的边,并使用连接不同集合的那些边制作一个新的(小)图,方法是:它们作为顶点连接的集合。
所有这些边缘都在至少一个MST中,因为Kruskal可能会首先选择它们。在新图中,作为桥的那些边中的任何一条都在每个 MST中,因为无论如何,Kruskal都会选择它们。参见:https://en.wikipedia.org/wiki/Bridge_(graph_theory)
因此,如下修改Kruskal的算法:
由于可以在线性时间内进行桥接查找,并且每个边缘最多在一个小图中,因此整个算法仍为O(| V | + | E | log | E |)。