[模板] Kruskal 求最小生成树

Kruskal求最小生成树

5/27/2020 9:28 更新:原来那个程序有点怪。。已经改了

运用了贪心的思想

最小生成树上的每条边一定是可选的最小边才能最优,其他情况均不是最优

因此将所有边加入小根堆,然后每次取堆顶

并查集维护连通性防止重复加边以及生成环

代码:

// Kruskal 

# include <iostream>
# include <cstdio>
# include <queue>
# define MAXN 5005
# define MAXM 200005

using namespace std;

struct edge{
    int u, v;
    int val;
    int next;
    bool operator > (const edge that) const{
        return this->val > that.val;
    }
}e[MAXM<<1], temp;

int head[MAXM<<1], cntEdge;

void addEdge(int u, int v, int val){
    e[++cntEdge].u = u, e[cntEdge].v = v, e[cntEdge].val = val;
    e[cntEdge].next = head[u], head[u] = cntEdge;
    return;
}

priority_queue<edge, vector<edge>, greater<edge> >q;

int fa[MAXN];

int find(int x){
    return fa[x] == x ? x : fa[x] = find(fa[x]);
}

void merge(int x, int y){
    x = find(x);
    fa[x] = y;
    return;
}

int n, m;
int main(){
    int ans = 0;
    cin>>n>>m;
    for(int i = 1; i <= n; i++)
        fa[i] = i;
    for(int i = 1; i <= m; i++){
        cin>>temp.u>>temp.v>>temp.val;
        q.push(temp);
    }
    for(int i = 1; i <= m; i++){
        temp = q.top();
        if(!(find(temp.u) == find(temp.v))){
            merge(temp.u, temp.v);
            ans += temp.val; // 统计总边权
        }
        q.pop();
    }
    for(int i = 2; i <= n; i++)
        if(find(i) != find(1)){
            cout<<"该图不连通!";
            return 0;
        }
    cout<<ans;

    return 0;
}

时间复杂度:\(O(E\log E)\)

原文链接: https://www.cnblogs.com/Foggy-Forest/p/12970301.html

欢迎关注

微信关注下方公众号,第一时间获取干货硬货;公众号内回复【pdf】免费获取数百本计算机经典书籍;

也有高质量的技术群,里面有嵌入式、搜广推等BAT大佬

    [模板] Kruskal 求最小生成树

原创文章受到原创版权保护。转载请注明出处:https://www.ccppcoding.com/archives/351220

非原创文章文中已经注明原地址,如有侵权,联系删除

关注公众号【高性能架构探索】,第一时间获取最新文章

转载文章受原作者版权保护。转载请注明原作者出处!

(0)
上一篇 2023年3月2日 上午6:44
下一篇 2023年3月2日 上午6:45

相关推荐