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

最小生成树

时间:2024-06-23 15:11:00浏览次数:3  
标签:int MST 最小 生成 算法 贪心

最小生成树

最小生成树也是一种常见的有权无向图问题,为了解决此问题,引出了本章的两个算法。

​ 本章将包括:

目录

一.基本概念

1.什么是最小生成树?

在一幅有权无向图中,把联通所有点且不含回路的一个子图称为一棵生成树,其中边权最小的生成树称为最小生成树(简称 \(MST\) )。

2. \(MST\) 算法的思路

\(MST\) 的计算有一个性质,即为最短的边一定在 \(MST\) 上,由是可以得出通过贪心来构建 \(MST\) ,因为为其满足“全局最优解由局部最优解组成”的最优性定理。

二. \(kruskal\) 算法

1.算法思路

\(kruskal\) 算法的思想为对每条边进行贪心,由于最短边一定在 \(MST\) 上这个原理,我们从最短的边开始,将其加入集合 \(T\) 中,在剩余的边中,找最短的边重复操作,直至 \(T\) 包含 \(n-1\) 条边或所有点都在集合 \(T\) 中。

由于 \(MST\) 不存在环,所以我们在进行操作时,要维护一个并查集结构,来保证其无环。

2.代码详解

由于其只用到了边的关系,我们只需维护一个简单的边集数组即可。

struct node{
    int u,v,w;                                //边集数组,u为起点,v为终点,w为边权
}e[maxn];
bool cmp(node a,node b){
    return a.w<b.w;                           //排序用的cmp函数,对边进行排序,找最小边
}
int fa[maxn];
int find(int x){                             //并查集的查询操作
    if(x!=fa[x])
        fa[x]=find(fa[x]);                   //路径压缩优化
    return fa[x];
}
int kruskal(){
    sort(e+1,e+m+1,cmp);
    for(int i=1;i<=n;i++) fa[i]=i;           //并查集初始化
    int ans=0;
    for(int i=1;i<=m;i++){
        int u=e[i].u,v=e[i].v,w=e[i].w;
        if(find(u)==find(v)) continue;       //若已是联通
        else{
            ans+=w;                          //统计答案
            fa[find(u)]=find(v);             //联通
        }
    }
    return ans;
}

3.算法总结

\(kruskal\) 算法编码较简单,无需邻接矩阵或是邻接表等复杂的存图方式,只需一个边集数组即可,具体处理方面也无需复杂的计算,只需进行一遍“排序+并查集”即可。

三. \(Prim\) 算法

1.算法思想

不同于 \(kruskal\) 算法对边进行贪心, \(Prim\) 算法注重对点进行贪心。以点为进一步贪心的线索,由生成树的定义可知,一棵生成树一定包含此图中的所有点。所以,我们可以以任意点为起点,进行 \(MST\) 的计算。

对于每个点来说,由于 \(MST\) 的性质,我们选择其出度权值最小的那一条,然后判断此边链接的点是否已在 \(MST\) 即可。是不是有点熟悉,是得,这与 \(Dijkstra\) 算法的贪心思路一致,不过是略微修改。

2.代码详解

int prim(){
    int s=1;                                   //若以1为起点
    for(int i=1;i<=maxn;i++) done[i]=false;    //初始化,done[i]表示点i是否在队列中
    priority_queue<node> q;                    //优先队列,存边权的长度
    q.push(node(s,0));
    int ans=0;
    while(!q.empty()){
        node u=q.top();
        q.pop();
        if(done[q.id]) continue;               //表示以在MST中,跳过
        done[q.id]=true;                       //标记存在
        ans+=q.w;
        for(int i=0;i<g[u.id].size();i++){     //枚举全部邻居
            edge y=g[u.id][i];
            if(done[y.to]) continue;           //若邻居已入队,跳过
            q.push(node(y.to,y.w));            //其邻居入队
        }
    }
    return ans;
}

3.算法总结

由代码可看出, \(Prim\) 算法与 \(Dijkstra\) 算法的代码十分相近,只是不用维护到起点的距离 \(dis\) 若 \(Prim\) 算法使用优先队列,则总复杂度为 \(O(mlog_2n)\) ;

四.总结

最小生成树是图论算法中较为重要的一种问题,当然其算法较为简单,但应充分理解其思想。

标签:int,MST,最小,生成,算法,贪心
From: https://www.cnblogs.com/adsd45666/p/18263463

相关文章

  • hyperf 生成二维码并且转为CMYK色彩通道的图片
    注意:CMYK色彩通道的图片格式需要为JPEG或TIFF,png是不支持CMYK的,不然转换的话会转换会srgb或Gray使用前先安装imagick拓展1{2"require":{3"ext-imagick":"*"4}5}  1publicfunctioncreateQrcode($data):void2{3//......
  • Stable Diffusion 生成个性图片指南
    在当今人工智能领域,midjourney无疑是生成图片的王者,但是苦于付费才能使用,今天我就给大家分享一下midjourney平替stablediffusion,实现本地生成不逊色于midjourney的图片效果图先上一个我自己生成的效果(就是在我的Mac上用CPU生成的)是不是非常棒?下面就让我们一起来深入探讨......
  • JAVA【案例5-2】模拟默认密码自动生成
    【模拟默认密码自动生成】1、案例描述本案例要求编写一个程序,模拟默认密码的自动生成策略,手动输入用户名,根据用户名自动生成默认密码。在生成密码时,将用户名反转即为默认的密码。2、案例目的(1)学会分析“模拟默认密码的生成”案例的实现思路(2)根据思路完成“模拟默认密码的......
  • C++U7-10-最小生成树
    本节课作业讲解视频:链接:https://pan.baidu.com/s/1lLlmhShdat9HuJWx7Rp_tA?pwd=0000提取码:0000  最小生成树是一种在无向图中寻找特定结构的算法结果,它具有多种实际应用。以下是关于最小生成树的一些主要应用:网络布局问题:在一个连通加权无向图中,最小生成树算法可以帮......
  • 2024年6月计算机视觉论文推荐:扩散模型、视觉语言模型、视频生成等
    6月还有一周就要结束了,我们今天来总结2024年6月上半月发表的最重要的论文,重点介绍了计算机视觉领域的最新研究和进展。DiffusionModels1、AutoregressiveModelBeatsDiffusion:LlamaforScalableImageGenerationLlamaGen,是一个新的图像生成模型,它将原始的大型语言模型......
  • TMPG ENC的开源替代品(内容由OpenAI 生成)
    TMPGEnc是一个流行的视频编码软件,但有几个开源替代品非常受欢迎,根据您的需求可能提供更好的功能:HandBrake:这是一个广泛使用的开源视频转码器。它支持多种格式,提供批处理功能,并且有一个用户友好的图形界面。HandBrake适用于大多数视频转换任务,并且可在Windows、Mac和Linux......
  • 977.有序数组的平方 ,209.长度最小的子数组 ,59.螺旋矩阵II
    977.有序数组的平方,209.长度最小的子数组,59.螺旋矩阵II977.有序数组的平方题目链接:977.有序数组的平方-力扣(LeetCode) 代码:classSolution{public:  vector<int>sortedSquares(vector<int>&nums){​    //intlength=end(nums)-begin(nums);......
  • MybatisPlus逆向工程插件,无需编写任何配置文件,只需配置数据库信息,一键生成Entity、Con
    文章目录1.前言2.与其它逆向工程工具相比的优势3.下载插件4.准备工作4.1创建数据库和表(可跳过)4.2配置数据库信息4.2.1打开IDEA的菜单栏4.2.2找到工具,点击ConfigDatabase4.2.3填写连接数据库所需要的信息4.3导入MybatisPlus的Maven依赖和SpringWeb的Maven依......
  • 2663. 字典序最小的美丽字符串
    题目如果一个字符串满足以下条件,则称其为美丽字符串:它由英语小写字母表的前k个字母组成。它不包含任何长度为2或更长的回文子字符串。给你一个长度为n的美丽字符串s和一个正整数k。请你找出并返回一个长度为n的美丽字符串,该字符串还满足:在字典序大于s的所......
  • 2024年华为OD机试真题-生成哈夫曼树-(C++/Java/python)-OD统一考试(C卷D卷)
    题目描述给定长度为n的无序的数字数组,每个数字代表二叉树的叶子节点的权值,数字数组的值均大于等于1。请完成一个函数,根据输入的数字数组,生成哈夫曼树,并将哈夫曼树按照中序遍历输出。为了保证输出的二叉树中序遍历结果统一,增加以下限制:二叉树节点中,左节点权值小于右节点......