文章

28

粉丝

226

获赞

53

访问

143.8k

头像
kruskal,解释并查集为何可以判断是否成环
推荐阅读
Sacan SVIP
P1312 浙江大学机试题
发布于2022年6月30日 11:11
阅读数 6.0k

#include <iostream>
#include <algorithm>
using namespace std;

const int maxn = 105;
int n,m;

struct edge{
    int u,v,w;
} edges[maxn];

// 并查集,用于确定构造最小生成树的过程中,加入一条边后不会生成环
// 原因:并查集里的每一个集合都是一个连通图(或连通分量),如果一条边的两个顶底都在同一个集合中,则加入这条边后必会成环
int fa[maxn];
int _find(int x){
    if(fa[x] == x){
        return x;
    }else{
        fa[x] = _find(fa[x]);
    }
    return fa[x];
}

// 克鲁斯科尔算法,每次选最小的边
bool cmp(edge a, edge b){
    return a.w < b.w;
}

int kruskal(){
    // 连通分量数目
    int cnt = m;
    sort(edges,edges+n,cmp);
    // 权值和
    int sum = 0;
    // 总边数。最终需要total = m-1
    int total = 0;
    for(int i = 0;i < n;i++){
        // 每次都选出当前权值最小的边
        edge now = edges[i];
        int x = now.u;
        int y = now.v;
        int w = now.w;

        // 利用并查集判断是否成环
        int fx = _find(x);
        int fy = _find(y);
        if(fx != fy){
            fa[fx] = fy;
            sum += w;
            total++;
            c...
登录查看完整内容


登录后发布评论

1 条评论
snake VIP
2024年3月20日 00:29

yes

赞(0)