【问题标题】:Necessary to MST edges in a graph图中 MST 边所必需的
【发布时间】:2019-01-03 16:52:55
【问题描述】:

给定一个 G(V,E) 加权(在边上)图,我需要找到属于每个 MST 的边数以及属于至少一个但不是全部的边数和那些不属于任何人。

图表以以下形式作为输入(示例):

3 3

1 2 1

1 3 1

2 3 2

前 3 是节点数,后 3 是边数。以下三行是边,第一个数字是它们的起点,第二个是它们的终点,第三个是值。

我曾考虑过运行 kruskal 一次以找到一个 MST,然后对于属于 G 的每个边检入(线性?)时间是否可以在不改变其整体重量的情况下替换此 MST 中的一条边。如果可以t 它不属于任何。如果它可以属于一个但不是全部。我还可以在第一个 MST 中标记边缘(可能带有第二个值 1 或 0),最后检查其中有多少不能被替换.这些是属于每个可能的 MST 的。这个算法可能是 O(V^2),我不太确定如何用 C++ 编写它。我的问题是,我们能以某种方式降低它的复杂性吗?如果我向 MST 添加一条边,我如何检查(并在 C++ 中实现)形成的循环是否包含一个重量较小的边?

【问题讨论】:

标签: algorithm graph


【解决方案1】:

您可以通过向 Kruskal 算法添加一些额外的工作来做到这一点。

在 Kruskal 算法中,具有相同权重的边可以按任何顺序排列,而实际检查它们的顺序决定了您从所有可能的 MST 中得到哪个 MST。对于每一个 MST,都有一个排序一致的边的顺序会产生那棵树。

无论使用什么排序一致的顺序,联合查找结构的状态在权重之间都是相同的。

如果只有 一个 特定权重的边,那么如果 Kruskal 算法选择它,它就在每个 MST 中,因为它将以任何排序一致的边顺序被选择,否则它是没有 MST。

如果有多个具有相同权重的边,并且 Kruskal 算法会选择其中至少一个,那么您可以在该点暂停 Kruskal 并制作一个新的(小)图,其中仅包含连接不同集合的那些边,使用它们作为顶点连接的集合。

所有这些边缘都在至少一个 MST 中,因为 Kruskal 可能会先选择它们。新图中的任何 边都在 每个 MST 中,因为无论如何 Kruskal 都会选择它们。见:https://en.wikipedia.org/wiki/Bridge_(graph_theory)

所以,修改克鲁斯卡尔算法如下:

  • 当 Kruskal 选择一条边时,在进行并集之前,收集并处理所有具有相同权重的非冗余边。
  • 使用这些边作为顶点连接的 find() 集制作一个小图
  • 使用 Tarjan 算法或等效算法(请参阅链接)查找图中的所有网桥。这些边在所有 MST 中。
  • 小图中的剩余边位于某些(但不是全部)MST 中。
  • 对小图中的边执行所有并集,然后继续下一个权重。

由于寻桥可以在线性时间内完成,并且每条边最多在一个小图中,所以整个算法仍然是O(|V| + |E| log |E|)。

【讨论】:

  • 我考虑过修改 kruskal 的算法,但以不同的方式。每次使用 find() 如果正在处理的边形成一个循环,检查在形成的循环中是否有另一个具有相同权重的边。如果这两个都在一个 mst 中使用,但不是全部。如果处理的边缘没有形成循环,则将其添加到 mst 并将其标记为包含在每个 mst 中的一个(但稍后可能会更改)。
猜你喜欢
  • 1970-01-01
  • 2012-06-03
  • 2017-01-21
  • 2018-05-16
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-01-06
相关资源
最近更新 更多