最小的生长树:Kruskal&拘谨的

时间:2014-04-29 22:16:45

标签: graph

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

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

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

1 个答案:

答案 0 :(得分:1)

  

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

不,Prims和Kruskals算法不必生成相同的MST。图形可以有许多MST,两种算法都可以生成不同的MST。但是两个MST的边缘类型必然是相同的。也就是说,如果你制作两个MST边缘的多重集合,那么两个多重集合肯定是相等的。您可以找到此here

的证明
  

如果图表有多个最小生成树,那么Kruskal的算法应该如何适应生成所有这些?

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

步骤1:对图表的边缘进行排序,如kruskals中所做。

步骤2:现在对于排序列表中的每个边缘,可能会发生两件事。边缘是在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)时间。