【问题标题】:Minimal spanning Trees: Kruskal & Prim最小生成树:Kruskal 和 Prim
【发布时间】:2014-06-16 01:50:56
【问题描述】:

我正在修改一个测试,遇到了两个与图表中的最小生成树相关的问题,我不确定并想测试我的答案。

第一个问题是:如果一个图有多个最小生成树,Kruskal 和 Prim 的最小生成树算法会生成相同的树吗?我认为它们不一定是因为算法不同。 Kruskal 依赖于边按权重排序,而 Prim 没有,因此它们可以从不同的顶点开始,从而生成不同的树。

第二个问题是:如果一个图有多个最小生成树,那么 Kruskal 的算法应该如何适应来生成所有这些?我认为需要允许通过顶点的循环结构,以便起始顶点每次都更改,因为边值可能相同。因此,通过将每个顶点依次作为起始顶点来生成树。换句话说,也是按顶点编号排序,而不是仅按边权重。

【问题讨论】:

    标签: graph


    【解决方案1】:

    如果一个图有多个最小生成树,Kruskal 和 Prim 的最小生成树算法会生成相同的树吗?

    不,Prims 和 Kruskals 算法不必生成相同的 MST。一个图可以有许多 MST,两种算法都可以生成不同的 MST。但是两个 MST 的边缘类型必然相同。即,如果您对两个 MST 的边进行多重集,那么这两个多重集肯定是相等的。你可以找到一个证明here

    如果一个图有多个最小生成树,应该如何调整 Kruskal 的算法来生成所有这些?

    似乎没有直接减少 kruskal 的 MST 算法来查找图中的所有 MST。你最好的选择是

    第 1 步:按照 kruskals 中的方式对图的边进行排序。

    Step2:现在对于排序列表中的每条边,可能会发生两件事。边要么在 MST 中,要么不在。因此,对于排序列表中的每条边,我们将遍历这两种情况,并创建两个新的 Union-Find 数据结构并在其他边上递归。

    伪代码:

    Step1: sort edges in ascending order
    Step2: now call printAllMsts(0, new UnionFind(V))
    
    void printAllMsts(int edgeNum, UnionFind U){
        if(edgeNum == edges.length){  // If no more edges to add
            if(U.numEdges == V-1){    // If U has V-1 edges, then we have an MST
                 printMst();
            }
            return;
        }
    
        if(edges[edgeNum+1] == edges[edgeNum]){
             printAllMsts(edgeNum+1, U); // when E is not taken in the MST   
        }
    
        edge E = edges[edgeNum];
        If(E can be a part of some MST){
            UnionFind newU = new UnionFind(U);
            newU.add(E);
        }
    
        printAllMsts(edgeNum+1, newU);
    }
    

    算法的运行时间将取决于图中边的数量和类型。该问题的最坏情况输入将是图中所有边的长度相同时。运行时间至少为 O(V*numberOfMsts),因为只要可能存在不同的 MST,就会克隆当前的 Union-Find 数据结构,这需要 O(V) 时间。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-05-12
      • 1970-01-01
      相关资源
      最近更新 更多