第二分钟成本生成树

时间:2010-04-22 16:30:46

标签: algorithm graph

我正在编写一种用于查找第二个最低成本生成树的算法。我的想法如下:

  1. 使用kruskals找到最低的MST。
  2. 删除MST的最低成本边缘。
  3. 在整个图表上再次运行kruskals。
  4. 返回新的MST。
  5. 我的问题是:这会有效吗?是否有更好的方法可以做到这一点?

9 个答案:

答案 0 :(得分:11)

考虑这种情况:

------100----
|           |
A--1--B--3--C
      |     |
      |     3
      |     |
      2-----D

MST由A-B-D-C组成(费用6)。第二个最低成本是A-B-C-D(成本7)。如果删除最低成本边缘,则会得到A-C-B-D(成本105)。

所以你的想法不会奏效。我虽然没有更好的想法......

答案 1 :(得分:11)

你可以在O(V 2 )中完成。首先使用Prim's algorithm计算MST(可以在O(V 2 )中完成。)

计算max[u, v] = the cost of the maximum cost edge on the (unique) path from u to v in the MST。可以在O(V 2 )中完成。

找到一个边缘(u, v),它不是最小化abs(max[u, v] - weight(u, v))的MST的一部分。可以在O(E)== O(V 2 )中完成。

返回MST' = MST - {the edge that has max[u, v] weight} + {(u, v)},这将为您提供第二好的MST。

Here's a link伪代码和更详细的解释。

答案 2 :(得分:4)

你可以这样做 - 尝试从图中一次删除MST的边缘,并运行MST,从中取出最小值。所以这与你的相似,除了迭代:

  1. 使用Kruskals查找MST。
  2. 对于MST中的每个边缘:
    1. 从图表中移除边缘
    2. 在MST上计算MST
    3. 跟踪最小的MST
    4. 将边缘添加回图表
  3. 返回最小的MST。

答案 3 :(得分:3)

这与拉里的答案相似。

找到MST后,

对于每个new_edge =不是MST中的边缘

  1. 将new_edge添加到MST。
  2. 找到形成的循环。
  3. 找到最大重量的边缘 循环不是非MST边缘 你补充道。
  4. 将重量增加记录为W_Inc = w(new_edge) - w(max_weight_edge_in_cycle)。
  5. 如果W_Inc< Min_W_Inc_Seen_So_Far然后
    • Min_W_Inc_Seen_So_Far = W_Inc
    • edge_to_add = new_edge
    • edge_to_remove = max_weight_edge_in_cycle
  6. 以下链接解决方案。
    http://web.mit.edu/6.263/www/quiz1-f05-sol.pdf

答案 4 :(得分:3)

轻微编辑你的算法。

    Use kruskals to find lowest MST.
    for all edges i of MST
        Delete edge i of the MST.
        Run kruskals again on the entire graph.
        loss=cost new edge introduced - cost of edge i
    return MST for which loss is minimum

答案 5 :(得分:1)

这是一个在O(n ^ 2)

中计算第二个最小生成树的算法
  1. 首先找出最小生成树(T)。不使用堆就需要O(n ^ 2)。
  2. 对T. = O(n ^ 2)
  3. 中的每个边e重复
  4. 让我们说当前的树边是e。这个树边将树分成两棵树,比如T1和T-T1。 e=(u,v)其中u在T1中,v在T-T1中。 = O(N ^ 2)

    对T-T1中的每个顶点v重复一次。 = O(N ^ 2)

    为T-T1中的所有v选择边e'=(u,v),e'在G(原始图形)中,它是最小的

  5. 计算新生树的重量。让我们说W=weight(T)-weight(e)+weight(e')

  6. 选择一个具有最小权重的T1

答案 6 :(得分:0)

你的方法不起作用,因为可能是min的情况。 MST中的权重边是一个桥(只有一条边连接图的2个部分),因此从集中删除此边将导致与一个MST相比新增2个MST。

答案 7 :(得分:0)

基于@IVlad的答案

O(V² log V)算法的详细说明

  • 使用Kruskal(或Prim)的算法查找最小生成树(MST),保存其总权重,并为MST中的每个节点存储其树邻居(即父级和所有子级)-> O(V² log V)
  • 计算最小生成树中任意两个顶点之间的最大边缘权重。从MST中的每个顶点开始,通过使用较早计算出的树节点邻居列表以深度或广度优先搜索遍历整棵树,并存储到目前为止在每个访问的新顶点处遇到的最大边缘权重。 -> O(V²)
  • 找到第二个最小生成树及其总权重。对于不属于原始MST的每个边,请尝试断开连接的两个顶点,方法是移除两个顶点之间最大权重的树边缘,然后将它们与当前考虑的顶点重新连接(注意:MST应该恢复为每次迭代后的原始状态)。总重量可以通过减去已删除边缘的重量并添加相加的边缘的重量来计算。存储获得的总重量中的最小值。

要练习,您可以尝试竞争性编程问题UVa 10600 - ACM Contest and Blackout,这涉及到按照OP的要求在加权图中找到第二个最小生成树。我的实现(在现代C ++中)可以在here中找到。

答案 8 :(得分:0)

MST 是一棵树,它具有图所有边的最小权重总和。因此,第二个最小 mst 将具有图中所有边的第二个最小总权重。

让 T -> BEST_MST(对图中的边进行排序,然后使用 kruskal 算法找到 MST)

T ' -> 第二个最好的 MST

假设 T 有 7 条边,现在要找到 T ' 我们将一条一条删除这 7 条边中的一条并找到该边的替代品(该边的成本肯定会大于我们刚刚从 T 中删除的边) ).

假设原始图有 15 条边

我们最好的 MST ( T ) 有 7 个边

和第二好的 MST ( T ' ) 也将只有 7 个边

如何找到T'

T 中有 7 条边,现在将所有这 7 条边一一删除并找到这些边的替换。

假设 MST 中的边 ( T ) --> { a,b,c,d,e,f,g }

假设我们的答案将是 2nd_BEST_MST 并且最初它具有无限值(我知道这听起来不太好,让我们暂时假设它)。

对于 BEST_MST 中的所有边:

current_edge = i 找到该边的替代品,该边的替代品肯定会比第 i 条边(7 条边之一)的权重更大 我们将如何使用 Kruskul 算法找到该边的替换(我们再次找到 MST,所以我们将仅使用 kruskal 算法,但这我们不必再次对边进行排序,因为我们在找到 BEST_MST ( T )。 将生成 NEW_MST 2nd_best_MST = min( NEW_MST , 2nd_best_MST ) 返回 2nd_best_MST 算法

假设原始图有 10 条边 找到 BEST_MST(使用 kruskal 算法)并假设 BEST_MST 只有 6 个边 弓还有 4 条边不在 BEST_MST 中(因为它们的权重值很大,其中一条边将为我们提供 2nd_Best_MST 对于 BEST_MST 中不存在的每条边“X”(即左 4 条边),将该边添加到 BEST_MST 中,这将创建循环 找到循环中权重最大的边 'K' (除了 new_ added_edge 'X' ) 暂时删除边“K”,这将形成一个新的生成树 计算权重差异并将 weight_difference 映射到边 'X' 。 对所有这 4 条边重复步骤 4,并将权重差异最小的生成树返回到 BEST_MST。