当前位置:首页 > 洛谷 > 洛谷1111题解题全解析:基于Kruskal算法与并查集的最小生成树实现

洛谷1111题解题全解析:基于Kruskal算法与并查集的最小生成树实现

2个月前 (06-15)

洛谷1111题解题全解析:基于Kruskal算法与并查集的最小生成树实现  Kruskal算法 最小生成树 并查集 图论算法 稀疏图处理 C++实现 第1张


一、题目解读

洛谷1111题是一道经典的图论问题,要求构建一个无向图最小生成树,并输出其最大边权值。题目核心在于通过给定的边集合,找到连接所有节点的最小权值子集,同时保证无环。这通常涉及最小生成算法(如Kruskal)的应用,需要高效处理边权重与节点连通性。

二、解题思路

代码采用Kruskal算法并查集的结合,巧妙解决最小生成树问题。其核心思路为:

    1. 贪心策略:按边权重递增排序,优先选择权值最小的边;

    2. 连通性判断:利用并查集快速合并节点,避免形成环。

通过这两个关键步骤,算法能在O(ElogE)复杂度下高效求解。

三、解题步骤

1. 输入与初始化:

    读取节点数N和边数M,创建边集合edges;

    初始化并查集parent数组(每个节点初始为自身根节点)。

2. 边排序:对edges按权值t升序排序,确保后续按权重递增处理。

3. 核心循环:遍历每条边,执行合并操作:

    通过find函数获取边两端节点的真实根节点;

    若根节点不同,合并节点并更新最大边权值max_t。

4. 结果判断:若合并次数达到N-1(即形成一棵树),输出max_t;否则输出-1(不连通)。

四、代码与注释

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

// 边结构(节点u、v及权值t)
struct Edge {
    int u, v, t;
    bool operator<(const Edge& other) const {
        return t < other.t; // 按权值排序比较函数
    }
};

vector<int> parent; // 并查集:记录节点的根节点

// 查找节点x的根节点(路径压缩优化)
int find(int x) {
    return parent[x] == x? x : parent[x] = find(parent[x]);
}

// 合并节点x与y,返回是否成功(避免环)
bool unite(int x, int y) {
    x = find(x); // 获取x的根
    y = find(y); // 获取y的根
    if(x == y) return false; // 同根则不合并
    parent[y] = x; // 合并y到x
    return true;
}

int main() {
    int N, M;
    cin >> N >> M;
    vector<Edge> edges(M);
    parent.resize(N+1); // 初始化并查集数组
    
    // 初始化:每个节点为独立根节点
    for(int i=1; i<=N; i++) parent[i] = i;
    // 输入边信息
    for(int i=0; i<M; i++) 
        cin >> edges[i].u >> edges[i].v >> edges[i].t;
    
    // 按权值排序
    sort(edges.begin(), edges.end());
    
    int cnt = 0, max_t = 0; // 合并次数与最大边权
    for(auto& e : edges) {
        // 若合并成功且未形成完整树,更新信息
        if(unite(e.u, e.v)) {
            max_t = max(max_t, e.t);
            if(++cnt == N-1) break; // 树已生成,退出循环
        }
    }
    
    // 根据连通性输出结果
    cout << (cnt == N-1? max_t : -1) << endl;
    return 0;
}

五、总结

本解法通过Kruskal算法与并查集的深度融合,实现了高效的最小生成树构建。其优势在于:

1. 时间复杂度优化:排序+并查集降低处理复杂度;

2. 代码简洁性:结构清晰,逻辑易懂,适合竞赛与工程场景。

该思路为同类图论问题提供了通用解决方案,尤其在稀疏图环境中表现优异。


原创内容 转载请注明出处

分享给朋友:

相关文章

2024蓝桥杯省赛B组“传送阵”题解(C++代码+图论算法优化)

2024蓝桥杯省赛B组“传送阵”题解(C++代码+图论算法优化)

一、题目解读2024年蓝桥杯省B组“传送阵”题目要求处理一个包含n个节点的图,节点间存在单向传输关系。每个节点i可传送至a[i]指定的节点,形成可能存在的环结构。题目需求解从任意节点出发能到达的最长路...

【力扣2846题】图论+二进制提升:高效解决连通性问题(附C++代码)

【力扣2846题】图论+二进制提升:高效解决连通性问题(附C++代码)

一、题目解读力扣2846题要求解决一个基于图连通性的操作优化问题。给定一个无向图,包含边权重,以及一系列查询,每个查询询问两点间路径的最小操作次数。题目关键在于高效计算路径上权重分布的统计信息,并转化...

NOI 2001密码锁(洛谷P2024)解题全解析:并查集+关系标记算法实战

NOI 2001密码锁(洛谷P2024)解题全解析:并查集+关系标记算法实战

一、题目解读2001年NOI密码锁(洛谷P2024)是一个经典的逻辑判断问题。题目描述了一个动物园中动物之间的关系,需要处理两种类型的陈述:同类关系(1)和捕食关系(2)。要求根据给定的K条关系,判断...

洛谷P3393题解:基于多源BFS与Dijkstra算法求解图论最小花费路径问题

洛谷P3393题解:基于多源BFS与Dijkstra算法求解图论最小花费路径问题

一、题目解读洛谷P3393题要求在一个包含N个城市和M条双向道路的图中,求解从起点1到终点N的最小花费路径。图中存在僵尸城市(僵尸无法通过)和危险城市(由僵尸城市扩散S步后标记),需要避开所有危险城市...

牛客3747题解析:二叉树序列化与反序列化(C++实现)

牛客3747题解析:二叉树序列化与反序列化(C++实现)

一、题目解读牛客3747题要求实现二叉树的序列化与反序列化功能。序列化即将二叉树转化为字符串,反序列化则将字符串还原为二叉树结构。题目核心在于设计高效的遍历与节点表示方法,需考虑空节点的处理,确保序列...

力扣765题:情侣牵手问题的并查集解法

力扣765题:情侣牵手问题的并查集解法

一、题目解读力扣765题要求在一个座位数组中,每对情侣需相邻而坐。给定n对情侣的初始座位安排(偶数长度数组),需通过最小次数的交换操作,使所有情侣成为相邻座位。二、并查集完整代码class ...

发表评论

访客

看不清,换一张

◎欢迎参与讨论,请在这里发表您的看法和观点。