码迷,mamicode.com
首页 > 编程语言 > 详细

算法实践--最小生成树(Kruskal算法)

时间:2019-01-16 00:16:57      阅读:255      评论:0      收藏:0      [点我收藏+]

标签:pre   kruskal算法   .com   har   --   介绍   ann   minimum   ges   

什么是最小生成树(Minimum Spanning Tree)

每两个端点之间的边都有一个权重值,最小生成树是这些边的一个子集。这些边可以将所有端点连到一起,且总的权重最小

下图所示的例子,最小生成树是{cf, fa, ab} 3条边

技术分享图片

 

Kruskal算法

用到上一篇中介绍的不相交集合(并查集)

首先,定义V是端点的集合,E是边的集合,A为要求的最小生成树集合

  • 初始A为空集合,每个端点都作为单独的不相交集合
  • 将所有边根据其权重进行排序
  • 对每条边(v1, v2),如果其两个端点数据不同的不相交集,则将该边加到集合A中,同时将v1和v2合并
  • 最终得到的A即为最小生成树

 

生成过程的示例图

技术分享图片技术分享图片技术分享图片技术分享图片技术分享图片技术分享图片

 

C++代码示例

 

struct Edge {
    char vertex1;
    char vertex2;
    int weight;
    Edge(char v1, char v2, int w):vertex1(v1), vertex2(v2), weight(w) {}
};

struct Graph {
    vector<char> vertice;
    vector<Edge> edges;
};

unordered_map<char, char> PARENT;
unordered_map<char, int> RANK;

char find(char vertex) {
    if (PARENT[vertex] == vertex) 
        return PARENT[vertex];
    else
        return find(PARENT[vertex]);    
}

void MST(Graph& g) {
    vector<Edge> res;

    for (auto c : g.vertice) {
        PARENT[c] = c;
        RANK[c] = 0;
    }

    sort(g.edges.begin(), g.edges.end(), [](Edge x, Edge y) {return x.weight < y.weight;});   // O(E*log(E))

    for (Edge e : g.edges) {         // O(E)
        char root1 = find(e.vertex1);  // 最差O(E),因为有记录深度,Find可以认为很快
        char root2 = find(e.vertex2);
        if (root1 != root2) {
            res.push_back(e);
            if (RANK[root1] > RANK[root2]) {
                PARENT[root2] = root1;
                RANK[root1]++;
            } else {
                PARENT[root1] = root2;
                RANK[root2]++;
            }
        }
    }

    for (Edge e : res) {
        cout << e.vertex1 << " -- " << e.vertex2 << "  " << e.weight << endl;
    }
}

void Union( char vertex_1, char vertex_2 ) {
}

int main() {

    char t[] = {a, b, c, d, e, f};

    Graph g;
    g.vertice = vector<char>(t, t + sizeof(t)/sizeof(t[0]));

    g.edges.push_back(Edge(a, b, 4));  // 稀疏图用链来表示(E = O(V)) 
    g.edges.push_back(Edge(a, f, 2));  // 如果是密集图(E = O(V*V)), 用矩阵来表示
    g.edges.push_back(Edge(f, b, 5));  // 大部分感兴趣的图是稀疏的
    g.edges.push_back(Edge(c, b, 6));
    g.edges.push_back(Edge(c, f, 1));
    g.edges.push_back(Edge(f, e, 4));
    g.edges.push_back(Edge(d, e, 2));
    g.edges.push_back(Edge(d, c, 3));

    MST(g);

    return 0;
}

 

算法实践--最小生成树(Kruskal算法)

标签:pre   kruskal算法   .com   har   --   介绍   ann   minimum   ges   

原文地址:https://www.cnblogs.com/logchen/p/10274863.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!