首页 > 编程语言 >Kruskal算法

Kruskal算法

时间:2024-02-06 14:22:07浏览次数:18  
标签:int Kruskal 一棵树 算法 edge 顶点 worth

问题描述

有一张 \(n\) 个顶点、\(m\) 条边的无向图,且是连通图,求最小生成树。

算法简析

\(Kruskal\) 是一种求最小生成树的算法。
设该图为 \(G = (V, E)\)。最小生成树即所求为 \(G_T = (V_T, E_T)\),因为图是连通的,所以最小生成树会覆盖所有的顶点,即 \(V == V_T\)。\(G_T\) 的真子图 \(G_A = (V_A, E_A)\),\(V_A == V\),构成森林(注意,这里与 \(Prim\) 并不一样。\(G_A\) 初始状态就覆盖所有顶点,每个顶点各自为一棵树)。
因为 \(G_A\) 已经覆盖了所有顶点,所以 \(G - G_A\) 只剩下 \(G\) 中所有的边 \(E\)。为了让 \(G_A\) 从森林变成一棵树,我们需要从 \(E\) 中挑选边加入 \(G_A\)。例如,我们选择 \(e(u, v)\) 加入 \(G_A\),本来独立的 \(u\) 和 \(v\) 被连接起来,相当于 \(u\) 和 \(v\) 各自所在的两棵树要合并成一棵树。
为了得到最小生成树,我们采用贪心策略,每次都从 \(E\) 中挑选最短的边 \(e(u, v)\),如果 \(u\) 和 \(v\) 还不在一棵树上,就将该边加入 \(G_A\),同时合并两棵树。
为了能够高效地合并树,我们采用并查集

代码

typedef struct
{
    int from, to, worth;
} edge;

vector<edge> E;

// Kruskal
bool cmp(const edge &a, const edge &b)
{
    return a.worth < b.worth;
}

int kruskal(void)
{
    int ret = 0;
    init();
    sort(E.begin(), E.end(), cmp);          // 升序
    for (int i = 0; i < E.size(); i++)
    {
        edge e = E[i];
        if (!same(e.from, e.to))            // 判断是否在一棵树中
        {
            ret += e.worth;
            unite(e.from, e.to);            // 合并树
        }
    }
    return ret;
}

标签:int,Kruskal,一棵树,算法,edge,顶点,worth
From: https://www.cnblogs.com/hoyd/p/18009631

相关文章

  • 代码随想录算法训练营第十三天 | 59.螺旋矩阵II 209.长度最小的子数组 977.有序数
    977.有序数组的平方 已解答简单 相关标签相关企业 给你一个按 非递减顺序 排序的整数数组 nums,返回 每个数字的平方 组成的新数组,要求也按 非递减顺序 排序。 示例1:输入:nums=[-4,-1,0,3,10]输出:[0,1,9,16,100]解释:平方后,数组变为[16......
  • 2024牛客寒假算法基础集训营1
    2024牛客寒假算法基础集训营1A.DFS搜索思路:看dfs其实就是一道字符题目#include<bits/stdc++.h>usingnamespacestd;stringx="dfs";stringy="DFS";voidsolve(){intn;cin>>n;stringst;cin>>st;intxx=0,yy=......
  • 文心一言 VS 讯飞星火 VS chatgpt (195)-- 算法导论14.3 3题
    三、用go语言,请给出一个有效的算法,对一个给定的区间i,返回一个与i重叠且具有最小低端点的区间;或者当这样的区间不存在时返回T.nil。文心一言,去掉math,代码正常运行:在Go语言中,你可以使用结构体来表示区间,并使用切片来存储区间集合。然后,你可以遍历区间集合,找到与给定区间重叠且具......
  • 【算法】位运算
    常见的位运算操作(操作对象为正整数时)1.按位与(&):当两个数全为1才为1,否则为0。两个数字做与运算,结果不会变大。2.按位或(|):当两个数中有一个1为1,否则为0。两个数字做或运算,结果不会变小。3.按位异或(^):两个数不同为1,相同为0.两个数字做异或运算,结果可能变大,也可能变小。异或的......
  • Prim算法
    问题描述有一张\(n\)个顶点、\(m\)条边的无向图,且是连通图,求最小生成树。Prim算法简析\(Prim\)算法是一种求最小生成树的算法。设该图为\(G=(V,E)\)。最小生成树即所求为\(G_T=(V_T,E_T)\),因为图是连通的,所以最小生成树会覆盖所有的顶点,即\(V==V_T\)。\(G_T\)......
  • 【算法专题】约数个数
    约数个数约数个数的普通求法首先我们根据数的唯一分解定理,对\(N\)进行分解得:\[N=p_1^{c_1}\timesp_2^{c_2}\timesp_3^{c_3}\times...\timesp_k^{c_k}\]由约数的定义:\(p_1^{c_1}=p_1^{0}\timesp_1^{1}\timesp_1^{2}\times...\timesp_1^{c_1}\)共有\(c_1......
  • 一套模板搞定二叉树算法题--二叉树算法讲解004
    1、二叉树经典习题模拟忘记知识点和技巧时,遇到一个新的二叉树习题,该如何处理思考和写代码解题?1.1、leetcode965题目和题意:题解1成员变量self.ans:题解2递归回传:1.2、leetcode257该题是个经典二叉树题目题目和题意:题解:分析,所有路径,每一个叶子节点都需要到达。到......
  • 2024牛客寒假算法基础集训营2(小白)
    A.TokitsukazeandBraceletCode:#include<bits/stdc++.h>usingnamespacestd;intmain(){intt;cin>>t;while(t--){inta,b,c,cnt=0;cin>>a>>b>>c;if(a>=150)cnt++;if(a>=200)......
  • 代码随想录算法训练营第十三天|239. 滑动窗口最大值 347.前 K 个高频元素 总结
    239.滑动窗口最大值题目链接:239.滑动窗口最大值-力扣(LeetCode)给你一个整数数组 nums,有一个大小为 k 的滑动窗口从数组的最左侧移动到数组的最右侧。你只可以看到在滑动窗口内的 k 个数字。滑动窗口每次只向右移动一位。返回 滑动窗口中的最大值 。思路:首先在不考虑......
  • 【算法专题】筛质数
    筛质数的三种方法什么是质数?只能够被1和它本身整除的数叫做质数1、朴素筛法那么我们从定义出发,假设我们要判断\(n\)是否是质数,我们从\(1\)开始枚举每一个数,一直到\(n\)看看有没有其他的数能够被\(n\)整除,如果没有,那么\(n\)就是质数。假设我们要筛出从\(1\)~......