惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

让小产品的独立变现更简单 - ezindie.com
让小产品的独立变现更简单 - ezindie.com
人人都是产品经理
人人都是产品经理
Cisco Talos Blog
Cisco Talos Blog
钛媒体:引领未来商业与生活新知
钛媒体:引领未来商业与生活新知
V
V2EX
博客园 - 三生石上(FineUI控件)
Martin Fowler
Martin Fowler
WordPress大学
WordPress大学
D
Docker
S
SegmentFault 最新的问题
博客园 - 聂微东
美团技术团队
Apple Machine Learning Research
Apple Machine Learning Research
月光博客
月光博客
奇客Solidot–传递最新科技情报
奇客Solidot–传递最新科技情报
Last Week in AI
Last Week in AI
M
MIT News - Artificial intelligence
F
Fortinet All Blogs
freeCodeCamp Programming Tutorials: Python, JavaScript, Git & More
The GitHub Blog
The GitHub Blog
GbyAI
GbyAI
L
LangChain Blog
Vercel News
Vercel News
博客园 - 叶小钗
MongoDB | Blog
MongoDB | Blog
Stack Overflow Blog
Stack Overflow Blog
H
Help Net Security
OSCHINA 社区最新新闻
OSCHINA 社区最新新闻
The Cloudflare Blog
Engineering at Meta
Engineering at Meta
T
Threat Research - Cisco Blogs
T
Threatpost
Scott Helme
Scott Helme
T
Tailwind CSS Blog
Latest news
Latest news
Stack Overflow Blog
Stack Overflow Blog
Blog — PlanetScale
Blog — PlanetScale
The Register - Security
The Register - Security
罗磊的独立博客
P
Proofpoint News Feed
腾讯CDC
S
Schneier on Security
雷峰网
雷峰网
A
About on SuperTechFans
T
Tenable Blog
F
Full Disclosure
Cyberwarzone
Cyberwarzone
博客园_首页
有赞技术团队
有赞技术团队
K
Kaspersky official blog

文章列表

5月月考 - faryou的博客 - 日记 faryou的博客-五一回老家 【汇编&硬件】时钟中断的具体实现 【汇编 - 功能】中断安装中断实现 faryou的博客-这些年,我不再看《熊出没》 【汇编&硬件】关机中断的具体实现 【汇编&硬件】网络连接相关中断的具体实现 faryou的博客-年初小记 【汇编&硬件】鼠标控制中断的具体实现 【汇编&硬件】声音输出中断的具体实现 【汇编&硬件】屏幕输出中断的具体实现 【汇编&硬件】磁盘读取中断的具体实现 【汇编&硬件】键盘读取中断的具体实现 【汇编】汇编环境的搭建及Debug的使用教程 【汇编】漫谈:学习汇编后的一些思考 faryou的博客-关于本站即日起实行“一站三体”运营制度 【汇编基础教程】完结篇 写在最后:前言 【汇编基础教程】使用BIOS的中断实现键盘输入及磁盘I/O 【汇编基础教程】中断 【汇编基础教程】端口 【汇编基础教程】标志寄存器 【汇编基础教程】寄存器和内存&一些基本命令的说明 【汇编基础教程】来存一些数据! 【汇编基础教程】段 【汇编基础教程】再谈栈 【汇编基础教程】更灵活的定位内存 【汇编基础教程】来写个“函数” 【汇编基础教程】理解一下[bx]和loop指令 【汇编基础教程】跳一跳! faryou的博客-我的竞赛经历&对人生的一些思考 faryou的博客-关于现在中小学计算机课的一些想法及思考 faryou的博客-2025年度总结 faryou的博客-临平山下十五年 faryou的博客-Windows 10即将停止支持,谈谈自己从小到大用电脑的感受 faryou的博客-谈谈一名10后的怀旧情怀 【汇编基础教程】8086CPU工作原理 【C语言】指针的理解与应用 【算法教程】【C/C++】DP(动态规划):区间DP——程序设计思路与代码实现 【算法教程】【C/C++】BFS(广度优先搜索)——程序设计思路与代码实现 【算法教程】【C/C++】DFS(深度优先搜索)——程序设计思路与代码实现 【算法教程】【C/C++】单源最短路径——程序设计思路与代码实现 【算法教程】【C/C++】并查集——程序设计思路与代码实现 【算法教程】【C/C++】DP(动态规划):背包DP——程序设计思路与代码实现 【算法教程】【C/C++】DP(动态规划):简单动规问题——程序设计思路与代码实现 【算法教程】【C/C++】递推——程序设计思路与代码实现 【算法教程】【C/C++】三分算法——程序设计思路与代码实现 【算法教程】【C/C++】二分答案——程序设计思路与代码实现 【算法教程】【C/C++】二分查找——程序设计思路与代码实现 【算法教程】【C/C++】贪心算法——程序设计思路与代码实现 【算法教程】【C/C++】基础数学:快排——程序设计思路与代码实现
【算法教程】【C/C++】最小生成树——程序设计思路与代码实现
faryou · 2024-09-22 · via

前言
最小生成树是指在一个无向图内,找出一棵树,使得各个结点之间能够互相到达,且总路径长度最短。

程序设计思路
最小生成树主要有两种思路——Kruskal和Prim,两者的时间复杂度为On2和On3,限于篇幅原因,故进行两者的讲解,只提供Kruskal的代码。
首先讲时间复杂度较高的Prim算法(有点像dijkstra):在图中先确定一个点,将该点加入队列,之后每次循环在与队列中的所有点连接的边中找出最短边(不得与之前已经在队列中的点相连),直到所有的点都被加入队列。
Kruskal是一种基于贪心的算法:每次在所有的边中找出最短边,判断其两端有没有与之前已经相连的点重复,直到所有点之间都已连接。因此,Kruskal需要进行排序操作。

代码实现
202408311725059767490453.png
这里只放Kruskal的代码:

#include <bits/stdc++.h>
struct tree{//存边,x、y分别代表两个端点,z为边权
    int x,y,z;
}tr[200005];

int n,m,iq,aq,sb=0,bin[5005],ans=0;//n、m如题意,iq、aq分别临时存放路径,sb用于计数(只拿n-1条边),bin存放每个点的路径,ans累加长度

int find(int a){//由于Kruskal基于树进行,可以使用路径压缩,详见并查集那篇文章
    int x=a;
    if(bin[x]!=x) return bin[x]=find(bin[x]);
    else return x;
}

bool cmp(tree a,tree b){//sort升序
    return a.z<b.z;
}

int main(){
    scanf("%d%d",&n,&m);
    for(int i=1;i<=m;i++){//读入
        scanf("%d%d%d",&tr[i].x,&tr[i].y,&tr[i].z);
        bin[tr[i].x]=tr[i].x;
        bin[tr[i].y]=tr[i].y;
    }
    sort(tr+1,tr+m+1,cmp);//升序排序
    for(int i=1;i<=m;i++){//遍历每条边
        iq=find(tr[i].x);//找当前边的x是否连入图中
        aq=find(tr[i].y);//找当前边的y是否连入图中
        if(iq==aq) continue;//当两者祖先相同时,直接跳过防止成环
        ans+=tr[i].z;//累加
        sb++;//计次
        bin[aq]=iq;//修改路径
        if(sb==n-1) break;//当要取的边数量足够时,退出循环
    }
    for(int i=1;i<n;i++) if(find(i)!=find(i+1)){//判断每个点的祖先是否相同
        printf("orz");
        return 0;
    }
    printf("%d",ans);
    return 0;
}

这里需要注意的是,由于我们已经完成了排序,故不需要在之后判断大小。

结语
本文中讲了Kruskal的思路及代码,并融入了并查集的知识。我是faryou,再见!