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

深度学习
• 阅读 3

洛谷1111题解:基于Kruskal算法与并查集的最小生成树实现 一、题目解读 洛谷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. 代码简洁性:结构清晰,逻辑易懂,适合竞赛与工程场景。

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

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

点赞
收藏
评论区
推荐文章
Wesley13 Wesley13
3年前
UOJ 176 新年的繁荣
挺妙的解法。发现边权很小,我们可以考虑从大到小枚举边权来进行$kruskal$算法,这样子对于每一个边权$i$,我们只要枚举$0\\leqj<m$,找到一个点使它的点权为$i|2^j$,尝试连边即可。另外,如果同一个点权重复出现,一定有办法使这个边权连满,这样子直接累加到答案里就可以了。时间复杂度$O(m\2^m)$,再套一个并
Wesley13 Wesley13
3年前
C语言递归之二叉树的最小深度
https://www.cnblogs.com/shichampion/p/12262678.html题目描述给定一个二叉树,找出其最小深度。最小深度是从根节点到最近叶子节点的最短路径上的节点数量。说明: 叶子节点是指没有子节点的节点。示例输入:3,9,20,null,null,15,7
Stella981 Stella981
3年前
Prim 普利姆算法
最小生成树之普利姆(Prim)算法如果想看克鲁斯卡尔算法(Kruskal),请移步\这是链接🔗{{\_<}}<(https://www.oschina.net/action/GoToLink?urlhttps%3A%2F%2Fwww.cnblogs.com%
Stella981 Stella981
3年前
Leetcode 783. 二叉搜索树结点最小距离
题目描述给定一个二叉搜索树的根结点root,返回树中任意两节点的差的最小值。!(https://uploadimages.jianshu.io/upload_images/97388075b2ef3e526250878.PNG?imageMogr2/autoorient/strip|imageView2/2/w/505)
贾蔷 贾蔷
5小时前
2023年GESP四级图像压缩题(洛谷B3851)解析与代码实现
一、题目解读本题要求实现图像压缩算法,通过处理输入的灰度图像数据(以十六进制表示的像素值),将其转换为压缩后的表示形式。核心目标是通过统计灰度频率,选取前16个高频灰度值构建压缩表,并利用最小距离替换将原始像素映射到压缩表索引,从而减少数据量。题目考察对数
深度学习 深度学习
5小时前
2024蓝桥杯省赛B组前缀总分(洛谷P12124)解题思路与代码详解
一、题目解读2024年蓝桥杯省B组题目“前缀总分”(对应洛谷P12124)要求计算给定字符串集合中,所有前缀的最长公共前缀(LCP)的总分,并找出通过移动字符位置后可能获得的最大总分。题目考察字符串处理与动态规划能力,需高效计算LCP并优化得分策略。二、解
深度学习 深度学习
5小时前
洛谷P2034题解:动态规划+单调队列优化求解最大K段子段和问题
一、题目解读洛谷P2034题目要求给定一个长度为n的整数数组,将其分成不超过k段,求各段和的最大值。该问题属于经典动态规划问题的扩展,需结合优化技巧高效求解。二、解题思路采用动态规划单调队列优化的策略。核心思想是定义状态dp
贾蔷 贾蔷
5小时前
【蓝桥杯2015省赛解析】生命之树(洛谷P8625):树形DP解题全攻略
一、题目解读“生命之树”是一道经典的树形结构问题,要求计算一棵带权树中,以某个节点为根的最大子树权值和。题目输入为n个节点及边信息,每个节点有权值wi,需找到所有节点中,子树权值和最大的节点,并输出其值。核心挑战在于如何处理树形结构的递归关系,并高效聚合子
深度学习 深度学习
5小时前
【CSP-S 2019】括号树(洛谷P5658):栈+DFS
一、题目解读括号树问题(洛谷P5658)要求处理一个由括号序列转化的树结构:每个节点表示一个括号,'('为子节点,')'为父节点。题目给定一棵n个节点的树,需计算每个节点的深度(括号层数),并输出所有节点深度与节点编号乘积的异或和。核心在于将括号序列转化为
贾蔷 贾蔷
5小时前
牛客13279题解:利用递归与深度优先搜索计算树的最大高度(附完整代码)
一、题目解读牛客13279题要求计算给定树的最大高度。题目输入一棵以邻接表形式表示的树(节点从0开始编号),需要输出从根节点到最深叶节点的最长路径长度。树的结构由n个节点和n1条边构成,保证为连通无环图。理解题目核心在于准确获取树的拓扑关系,并设计算法遍历