当前位置:首页 > 技术 > 正文内容

使用Kruskal算法求解最小生成树

访客 技术 2026年10月15日 1

问题描述

给定一个无向图,要求计算其最小生成树。如果该图不连通,则输出 "orz"。

输入格式

第一行包含两个整数 N 和 M,表示图中有 N 个节点和 M 条无向边。接下来的 M 行每行包含三个整数 X, Y, Z,表示有一条长度为 Z 的无向边连接节点 X 和 Y。

输出格式

如果图是连通的,输出一个整数表示最小生成树的所有边的总长度。如果图不连通,则输出 "orz"。

样例输入

6 9
2 4 11
3 5 13
4 6 3
5 6 4
2 3 6
4 5 7
1 2 1
3 4 9
1 3 2

样例输出

19

数据规模

  • 对于 20% 的数据,N≤5,M≤20。
  • 对于 40% 的数据,N≤50,M≤2500。
  • 对于 70% 的数据,N≤500,M≤10^4。
  • 对于 100% 的数据,1≤N≤5000,1≤M≤2×10^5。

最小生成树的定义

最小生成树是指在一个连通无向图中,用最少的边使所有节点连通,并且这些边的总权重最小。一个有 n 个节点的连通无向图至少需要 n-1 条边来保持连通,且不包含环。

Kruskal 算法(贪心)

适用于稀疏图(M 远大于 N)。Kruskal 算法的基本思想是首先对所有的边按权重从小到大排序,然后依次选择最短的边加入生成树,直到选择了 n-1 条边为止。在选择过程中,需要避免形成环,可以使用并查集来高效地判断两个节点是否已经连通。

算法实现步骤

  1. 对所有边按权重进行排序。
  2. 初始化并查集,每个节点的父节点指向自己。
  3. 遍历排序后的边,如果两个节点尚未连通,则将这条边加入生成树,并合并这两个节点所在的集合。
  4. 当生成树中的边数达到 n-1 时,算法结束。

时间复杂度

对边进行快速排序的时间复杂度为 O(MlogM),在 m 条边中找出 n-1 条边的时间复杂度为 O(MlogN),因此 Kruskal 算法的总时间复杂度为 O(MlogM + MlogN)。通常情况下 M 比 N 大很多,所以时间复杂度主要由 O(MlogM) 决定。

代码实现


#include <bits/stdc++.h>
using namespace std;

int n, m, fa[1000001], countt, sum;
struct Edge {
    int u, v, w;
} edges[1000001];

bool compare(Edge a, Edge b) {
    return a.w < b.w;
}

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

bool unite(int x, int y) {
    x = find(x);
    y = find(y);
    if (x == y) return false;
    fa[y] = x;
    return true;
}

void kruskal() {
    for (int i = 1; i <= m; i++) {
        if (unite(edges[i].u, edges[i].v)) {
            countt++;
            sum += edges[i].w;
        }
        if (countt == n - 1) return;
    }
}

int main() {
    cin >> n >> m;
    for (int i = 1; i <= m; i++) {
        cin >> edges[i].u >> edges[i].v >> edges[i].w;
    }
    sort(edges + 1, edges + m + 1, compare);
    for (int i = 1; i <= n; i++) fa[i] = i;
    kruskal();
    if (countt == n - 1) cout << sum;
    else cout << "orz";
    return 0;
}
标签: 最小生成树

相关文章

Linux crontab 详解

1) crontab 是什么cron 是 Linux 的定时任务守护进程;crontab 是用来编辑/查看“按时间周期执行命令”的表(cron table)。常见两类:用户 crontab:每个用户一份(crontab -e 编辑)系统级 crontab / cron.d:可指定执行用户(/etc/crontab、/etc/cron.d/*)2) crontab 时间...

富文本里可以允许的 HTML 属性

一、所有标签默认允许的安全属性(极少)class        (可选)id           (通常建议禁用)title️ 注意:id 容易被滥用做锚点注入,很多系统直接禁用class 允许的话最好只允许固定前缀(如 editor-*)二、a 标签允许属性<a href="" t...

Mac 安装 Node.js 指南

方法一:通过官网安装包(最简单,适合初学者)如果你只是想快速安装并开始使用,这是最直接的方法。访问 Node.js 官网。页面会显示两个版本:LTS (Recommended For Most Users):长期支持版,最稳定。建议选这个。Current:最新特性版,包含最新功能但可能不够稳定。下载 .pkg 安装包并运行。按照安装向导点击“下一步”即可完成。方法二:使用 Homebrew 安装(...

Dom\HTML_NO_DEFAULT_NS 的副作用:自动加闭合标签

在使用Dom\HTMLDocument时,Dom\HTML_NO_DEFAULT_NS 将禁止在解析过程中设置元素的命名空间, 此设置是为了与DOMDocument向后兼容而存在的。当使用它时,已知的一个副作用就是:自动加闭合标签例如 </img> 为什么会这样?当你使用:Dom\HTML_NO_DEFAULT_NS文档会变成 无命名空间模式,此时内部更接近 XML...

linux screen 用法详情 (nohup 的替代方案)

一、screen 是什么?能干嘛?screen 是一个终端复用器,可以:在一个 SSH 会话中开多个“虚拟终端”SSH 断线后,程序仍然在后台运行随时重新连接到原来的会话特别适合:nohup 的替代方案跑脚本 / 爬虫 / 训练模型运维、远程开发二、安装 screen# CentOS / Rocky / Almayum install -y screen# Debian / Ubuntuapt i...

PHPStan 有什么用?怎么用?

PHPStan 是一个 PHP 的静态分析工具,在不运行代码的情况下就能帮你发现潜在问题,比如:传错类型(把 string 传给接受 int 的函数)访问不存在的属性 / 方法null 没处理好永远不会执行到的代码数组 key/值类型不一致返回值不符合声明注释和真实类型不匹配它非常适合:想提升代码质量、减少线上 bug、统一团队风格的人(尤其是中大型项目)。一、PHPStan 有什么用(通俗点说)...

发表评论

访客

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