首页 > 其他分享 >Kruskal最小生成树

Kruskal最小生成树

时间:2024-06-02 23:22:43浏览次数:25  
标签:return int Kruskal 最小 生成 fa 算法

Kruskal最小生成树

Kruskal最小生成树 是求解图G的最小生成树(最优树)T 的算法。Kruskal算法是基于边来构造的算法,相对好理解。还有一个Prim算法是从点方面考虑的构建方式。

对于图 \(G(V,E)\) ,Kruskal算法的时间复杂度是 \(O(|E| \cdot \alpha(V))\) ,其中α为Ackermann函数,其增长非常慢,我们可以视为常数。所以Kruskal算法的时间复杂度为 \(O(E \log(E))\).


Kruskal算法运行步骤如下:

设权图 \(G = (P, L)\) 是连通的。

  1. 取 $l_1 \in L(G) $ ,使 \(\omega(l_1)\) 最小。
  2. 如果 \(l_1,l_2, ...,l_i\) 已经得到,则从 $L(G) - {l_1,l_2,...,l_i} $ 中取 \(l_{i+1}\) ,使得 \(\{l_1,l_2,...,l_i,l_{i+1} \}\) 组成无回路的图,并且 \(\omega(l_{i+1})\) 最小,如果不存在这样的 \(l_{i+1}\) ,则算法停止。

以上来自《离散数学结构》


至于代码怎么写。

我们先存下所有的边,将所有边按照边权排序。然后开始按顺序枚举每一条边,如果会成环则跳过,不成还就加入,直到所有边都枚举完成。

其中如何判断成环,我们需要用到并查集。每次加入一条边时,我们把起点和终点加入一个并查集中。判断成环时,只需要判断新加的这条边的起点终点是否在同一个并查集中即可。

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int INF = 0x3f3f3f3f;
const int maxn = 1000010;

struct Edge {
    int x, y, value;
} edge[maxn];
int fa[maxn];
int n, m, p;
int x, y;
int res;

bool com(Edge x, Edge y) {  //排序函数
    if (x.value < y.value) return true;
    else return false;
}

//并查集操作
int find(int x) {
    if (fa[x] == x) return x;
    return fa[x] = find(fa[x]);
}
void combine(int x, int y) {
    int fx = find(x), fy = find(y);
    fa[fx] = fy;
    return;
}

//Kruskal算法
int Kruskal() {
    int ans = 0, cnt = 0;
    for (int i = 1; i <= m; i++) {
        if (find(edge[i].x) != find(edge[i].y)) {   //判断加上这条边之后是否会形成回路
            combine(edge[i].x, edge[i].y);  //不会,则合并
            cnt++;
            ans = ans + edge[i].value;  //记录答案
        }
        if (cnt == n - 1) break;    //n-1条边代表已经提前生成完成了
    }
    if (cnt < n - 1) return -1; //枚举完所有边之后任然不足 n-1条边,则不存在最小生成树 orz
    return ans;
}

int main() {
    scanf("%d%d", &n, &m);
    for (int i = 1; i <= n; i++) fa[i] = i;
    for (int i = 1; i <= m; i++) {
        scanf("%d%d%d", &edge[i].x, &edge[i].y, &edge[i].value);
    }
    sort(edge + 1, edge + m + 1, com);
    res = Kruskal();
    if (res == -1) printf("orz\n");
    else printf("%d\n", res);
    return 0;
}

标签:return,int,Kruskal,最小,生成,fa,算法
From: https://www.cnblogs.com/pengcheng-official/p/18227809

相关文章

  • 【Python】生成html文档-使用dominate
    原文地址:https://www.cnblogs.com/kaerxifa/p/13035376.htmldominate简介dominate是一个使用优雅的DOMAPI创建和操作HTML文档的Python库。使用它能非常简洁地编写纯Python的HTML页面,这消除了学习另一种模板语言的需要,利用Python更强大的特性。 首先安装依赖:pipinstall......
  • 【大模型应用开发极简入门】构建新闻稿生成器:提示词的使用与基于事实的提示词
    文章目录一.提示词怎么写二.完整代码三.基于事实的promptGPT-4和ChatGPT等LLM专用于生成文本。我们可以使用GPT-4和ChatGPT在各种场景中生成文本,举例如下。电子邮件合同或正式文档创意写作逐步行动计划头脑风暴广告职位描述对于本项目,我们将创建一个工具,它可......
  • 代码随想录算法训练营第二十一天 | 530.二叉搜索树的最小绝对差 501.二叉搜索树中的众
    530.二叉搜索树的最小绝对差题目链接文章讲解视频讲解关键词:二叉搜索树-->中序遍历关于递归的返回值  由于需要遍历整棵二叉树,所以返回值为void,如果不是遍历整棵二叉树,需要在得到结果时立即返回结果,此时返回值才不为空怎样使用两个指针pre和cur使得pre始终指向cur的前......
  • 20、matlab信号波形生成:狄利克雷函数、高斯脉冲和高斯脉冲序列
    1、狄利克雷函数生成波形diric()函数语法:y=diric(x,n)返回n次的狄利克雷函数对输入数组x的元素求值。1)diric()函数代码x=linspace(-2*pi,2*pi,301);%定义x取值d6=diric(x,6);d7=diric(x,7);subplot(2,1,1)plot(x,d6)ylabel('n=6')title('狄利克雷函数')su......
  • 实验 5 语义分析和中间代码生成器 (Price 600)
    WX:help-assignmentcodeprice600实验5语义分析和中间代码生成器语义分析器分两部分,第一部分为赋值表达式,第二部分为数组、布尔表达式和控制语句。要求参考课本6.4.2、6.4.3和7.3、7.4、7.5,实现递归下降翻译器。注意数据结构:四元式:结构体四元式序列:结构体数......
  • 阿里妈妈->创意图片生成
    数智商业技术2.0时代的新「三驾马车」,阿里妈妈郑波谈如何把握生成式大模型ACM\x26#39;23中国图灵大会SIGAIChina论坛上,阿里妈妈及闲鱼CTO郑波分享关于数智商业技术的洞见。他认为在这轮生成式AI大模型的驱动下,数智商业技术将进入2.0时代,其中知识驱动、逻辑推理和创造......
  • excel生成insert语句
    在Excel中使用VBA生成INSERT语句通常涉及遍历工作表中的数据,并根据数据内容构造SQL语句。以下是一个基本的示例步骤和VBA代码片段,说明如何实现这一过程: ###步骤说明:1.**打开Excel**,确保你的数据已经整理好,每一列对应数据库表的一个字段。2.**启用开发者选项卡**(如果尚......
  • Day 10:100322. 删除星号以后字典序最小的字符串
    Leetcode100322.删除星号以后字典序最小的字符串给你一个字符串s。它可能包含任意数量的‘’字符。你的任务是删除所有的'’字符。当字符串还存在至少一个‘*’字符时,你可以执行以下操作:删除最左边的‘*’字符,同时删除该星号字符左边一个字典序最小的字符......
  • Day 9:2829. k-avoiding 数组的最小总和
    Leetcode2829.k-avoiding数组的最小总和给你两个整数n和k。对于一个由不同正整数组成的数组,如果其中不存在任何求和等于k的不同元素对,则称其为k-avoiding数组。返回长度为n的k-avoiding数组的可能的最小总和。n个不同正整数的最小总和,那就是从1......
  • linux 系统上图形生成错误 java.lang.NoClassDefFoundError: Could not initialize cl
    错误信息:02-Jun-202409:11:09.421SEVERE[Thread-32]org.apache.catalina.core.StandardWrapperValve.invokeServlet.service()forservlet[springDispatcherServlet]incontextwithpath[]threwexception[Handlerdispatchfailed;nestedexceptionisjava.lang.......