Kruskal算法

Kruskal算法按照边的权值的顺序从小到大查看一遍,如果不产生圈(重边等也算在内),就把当前这条边加入到生成树中。

如何判断是否产生圈:

假设要把顶点 u 和顶点 v 的边e加入生成树中。如果加入之前 u 和 v 不在同一个连通分量里,那么加入 e 也不会产生圈。反之,如果 u 和 v 在同一个连通分量里,那么一定会产生圈。可以使用并查集高效地判断是否属于同一个连通分量。

Kruskal算法在边的排序上最费时,算法的复杂度是O(|E|log|V|)。

代码:

struct edge {
    int u;
    int v;
    int cost;
};

bool comp(const edge& e1, const edge& e2) {
    return e1.cost < e2.cost;
}

edge es[MAX_E];
int V, E;

int Kruskal() {
    //按照edge.cost的顺序从小到大排序 
    sort(es, es + E, comp);
    //并查集的初始化 
    init_union_find(V);
    int res = 0;
    for(int i = 0; i < E; ++i) {
        edge e = es[i];
        if(!same(e.u, e.v)) {
            unite(e.u, e.v);
            res += e.cost;
        }
    }
    return res;
}

results matching ""

    No results matching ""