图的最小生成树,Kruskal算法

Posted fish-fly

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了图的最小生成树,Kruskal算法相关的知识,希望对你有一定的参考价值。

最小生成树 kruskal 算法,适用于边稀疏的图,

  先按照边进行排序。

  取出小的边

  选出小的,判断边的两个顶点是否是同一连通分量。如果是则继续取出下一个边。否则输出两个顶点,并合并两个连通分量。

 

  需要注意的是一开始需要一个辅助数组来记录连通分量,初始化所有顶点自己是一个连通分量。当合并两个连通分量时,需要遍历这个数组,将其中一个设置成另一个连通分量的值。

 

  

struct Edge{
    int head;
    int tail;
    int lowcost;
};

bool compare(const Edge& e1, const Edge& e2) {
    return e1.lowcost < e2.lowcost;
}
void MiniSpanTree_Kruskal(vector<vector<int> > G) {
    int m = G.size();
    vector<Edge> edge;
    vector<int> Vex(m);//连通分量
    //将图转成边存储
    for(int i = 0;i<m;i++){
        Vex[i] = i;//初始连通分量为其自身
        for(int j = 0;j<m;j++){
            if(j == i || G[i][j] == -1) continue;
            Edge e;
            e.head = i;
            e.tail = j;
            e.lowcost = G[i][j];
            edge.push_back(e);
        }
    }
    sort(edge.begin(),edge.end(),compare);
    for(int i = 0;i<edge.size();i++){
        int v0 = edge[i].head, v1 = edge[i].tail;
        if(Vex[v0] == Vex[v1]) continue; // 如果v0和v1是同一个连通分量,就找下一个
        cout<<v0<<v1;
        int temp = Vex[v1];
        for(int j = 0;j<m;j++){
            if(Vex[j] == temp) {
                Vex[j] = Vex[v0]; //更新v1的连通分量,并入到v0
            }
        }
    }
}

  

以上是关于图的最小生成树,Kruskal算法的主要内容,如果未能解决你的问题,请参考以下文章

C++ 实现无向图的最小生成树Kruskal算法(完整代码)

图的最小生成树——Kruskal算法

急求KRUSKAL算法求最小生成树过程演示

图解:如何实现最小生成树(Prim算法与Kruskal算法)

最小生成树—— Kruskal算法

无向带权图的最小生成树算法——Prim及Kruskal算法思路