题解 | 还是畅通工程 kruskal算法、贪心算法、并查集

还是畅通工程

https://www.nowcoder.com/practice/d6bd75dbb36e410995f8673a6a2e2229

#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <vector>
#include <algorithm>
using namespace std;

// 全局数组
int father[1010];

// 结构体 边
struct Edge {
    int u;
    int v;
    int weight;  // 带权图
    // 构造函数的特点 类里面 没有返回值 名字和类名相同
    Edge(int _u, int _v, int _weight) {
        u = _u;
        v = _v;
        weight = _weight;
    }
};

// 初始化
void InitDisjoinSet(int n) {
    for (int i = 0; i < n; i++) {
        father[i] = i;
    }
}

// 查找指定元素的根节点
int FindDisjoinSet(int u) {
    if (u == father[u]) {
        return u;
    } else {
        father[u] = FindDisjoinSet(father[u]);
        return father[u];
    }
}

// 合并
void UnionDisjoinSet(int u, int v) {
    int uroot = FindDisjoinSet(u);
    int vroot = FindDisjoinSet(v);
    father[vroot] = uroot;
}

// 权值排序 比较函数
bool compare(Edge lhs, Edge rhs) {
    // 权值 从小到大 升序
    return lhs.weight < rhs.weight;
}

int main() {
    int n;
    while (scanf("%d", &n) != EOF) {
        if (n == 0) {
            break;
        }
        vector<Edge> edgeVec;
        InitDisjoinSet(n + 1);   // 只使用 1 -> n
        for (int i = 0; i < n * (n - 1) / 2; i++) {
            int u, v, weight;
            scanf("%d%d%d", &u, &v, &weight);
            // Edge e;  // 可以用类的构造函数简化
            // e.u = u;
            // e.v = v;
            // e.weight = weight;
            Edge e(u, v, weight);
            edgeVec.push_back(e);
        }
        //  kruskal
        // 1.权值排序
        sort(edgeVec.begin(), edgeVec.end(), compare);

        // 2.遍历edgeVec加入子图
        int totalWeight = 0;  // 树的总权重
        int curEdgeNum = 0;  // 边数
        vector<Edge>::iterator it;
        for (it = edgeVec.begin(); it != edgeVec.end(); it++) {
            // 不连通才加入
            if (FindDisjoinSet(it->u) != FindDisjoinSet(it->v)) {
                UnionDisjoinSet(it->u, it->v);  // u 到 v 之间连一条边,保证联通
                curEdgeNum++;
                totalWeight += it->weight;
            }
            if (curEdgeNum == n - 1) {  // 3. 边数 = 顶点数 - 1
                break;
            }
        }

        printf("%d\n", totalWeight);
    }
    return 0;
}

#复试练习##考研#
2025考研复试 文章被收录于专栏

复试ing,努力中。。。

全部评论

相关推荐

评论
点赞
收藏
分享

创作者周榜

更多
牛客网
牛客企业服务