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

推荐订阅源

L
LangChain Blog
Scott Helme
Scott Helme
D
Darknet – Hacking Tools, Hacker News & Cyber Security
Stack Overflow Blog
Stack Overflow Blog
Forbes - Security
Forbes - Security
T
The Blog of Author Tim Ferriss
Y
Y Combinator Blog
S
Schneier on Security
cs.CV updates on arXiv.org
cs.CV updates on arXiv.org
Cisco Talos Blog
Cisco Talos Blog
N
News | PayPal Newsroom
H
Hackread – Cybersecurity News, Data Breaches, AI and More
Project Zero
Project Zero
Cyberwarzone
Cyberwarzone
Vercel News
Vercel News
M
MIT News - Artificial intelligence
云风的 BLOG
云风的 BLOG
Google Online Security Blog
Google Online Security Blog
Simon Willison's Weblog
Simon Willison's Weblog
MongoDB | Blog
MongoDB | Blog
Martin Fowler
Martin Fowler
T
Tenable Blog
I
InfoQ
W
WeLiveSecurity
Google DeepMind News
Google DeepMind News
G
Google Developers Blog
D
DataBreaches.Net
博客园 - Franky
Know Your Adversary
Know Your Adversary
Spread Privacy
Spread Privacy
S
Security @ Cisco Blogs
Hacker News: Ask HN
Hacker News: Ask HN
J
Java Code Geeks
Threat Intelligence Blog | Flashpoint
Threat Intelligence Blog | Flashpoint
F
Full Disclosure
C
Cisco Blogs
Google DeepMind News
Google DeepMind News
P
Proofpoint News Feed
C
CXSECURITY Database RSS Feed - CXSecurity.com
The Cloudflare Blog
cs.AI updates on arXiv.org
cs.AI updates on arXiv.org
I
Intezer
The GitHub Blog
The GitHub Blog
freeCodeCamp Programming Tutorials: Python, JavaScript, Git & More
F
Fortinet All Blogs
Jina AI
Jina AI
V
Visual Studio Blog
L
LINUX DO - 热门话题
WordPress大学
WordPress大学
aimingoo的专栏
aimingoo的专栏

AirTouchの小站

DNSMgr——聚合管理所有域名DNS解析+自动续签SSL证书并部署 | AirTouchの小站 雨云香港服务器简单测评 | AirTouchの小站 七牛云 AI 狂送 token 实测到底怎么样 | AirTouchの小站 记一次博客被攻击 | AirTouchの小站 给你的 Artalk 评论区配置验证码和垃圾评论检测 | AirTouchの小站 抓紧上车!免费 E3 开发者账号又来了! | AirTouchの小站 Vercel & Cloudflare Worker 项目推荐(2) | AirTouchの小站 用 Zmail 搭建自己的临时邮箱 | AirTouchの小站 IPv6反解域名?手把手带你搞 | AirTouchの小站 AirTouchの小站 AirTouchの小站 AirTouchの小站 AirTouchの小站 AirTouchの小站 macOS Tahoe 26中Electron架构卡顿的临时解决方案 | AirTouchの小站 用Obsidian插件增强Stellar写作体验 | AirTouchの小站 2025苹果秋季发布会亮点总结 | AirTouchの小站 分享几个artalk邮件通知模板 | AirTouchの小站 博客的图片应该存哪啊? | AirTouchの小站 Pic Smaller——自部署压缩图片的利器 | AirTouchの小站 企业微信的自定义域名邮箱太香了 | AirTouchの小站 所有道听途说,终获眼见为实 | AirTouchの小站 修复Vercel部署hexo导致文章的更新时间错误 | AirTouchの小站 jsDelivr国内公益加速镜像分享 | AirTouchの小站 搭建自己的busuanzi访问量统计服务 | AirTouchの小站 用Vercel和Netlify反代你的网站 | AirTouchの小站 用EdgeOne配置反向代理 丢掉丑陋的端口号 | AirTouchの小站 拼好鸽香港4区nat机器:月付3.5还要啥自行车! | AirTouchの小站 博客的新域名——xsl.im | AirTouchの小站 如何搭建自己的EdgeOne优选域名 | AirTouchの小站 用EdgeOne加速CloudflareR2存储桶 | AirTouchの小站 EdgeOne自动化上传证书并部署 | AirTouchの小站 你需要把PicGo换成PicList了! | AirTouchの小站 Cursor屏蔽中国大陆?给你解决方案! | AirTouchの小站 使用 Cloudflare Workers 自动获取必应每日壁纸 | AirTouchの小站 题解:P9509『STA - R3』Aulvwc | AirTouchの小站 题解:P11140 [APC001] E - Linear Map | AirTouchの小站 Phira多人联机服务器搭建&使用教程 | AirTouchの小站 腾讯云EdgeOne免费CDN加速你的网站 | AirTouchの小站 Hexo 博客收录指南 | AirTouchの小站 题解:P12646 [KOI 2024 Round 1] 升序 | AirTouchの小站 Cloudflare CDN优选IP加速你的网站 | AirTouchの小站 Giffgaff在线生成esim二维码 | Giffgaff sim转eSIM指南 | AirTouchの小站 AirTouchの小站 AirTouchの小站 Hexo Stellar 主题装修笔记 | AirTouchの小站 AirTouchの小站 AirTouchの小站 AirTouchの小站
复习一下最小生成树 | AirTouchの小站
AirTouch, me@airtouch.top · 2025-09-15 · via AirTouchの小站

最小生成树是什么

在一个连通无向带权图中,最小生成树是指

  • 一个子图,它是一棵树(无环、连通)
  • 包含原图的所有顶点
  • 所有边的权重之和最小

Prim

加点法

从任意一个顶点开始,每次选择一条连接已选顶点集和未选顶点集的最小权边,并将该边连接的顶点加入已选集。逐步扩张,直到包含所有顶点。

算法步骤

  1. 随机选择一个起始顶点,加入集合 UU(已选顶点集)。
  2. 在所有连接 UU 内顶点和 UU 外顶点的边中,选择一条权重最小的边 (u,v)(u, v)(其中 uuUU 中,vv 不在 UU 中)。
  3. 将顶点 vv 加入集合 UU ,边 (u,v)(u, v) 加入最小生成树。
  4. 重复步骤2、3,直到 UU 包含所有顶点。

时间复杂度

  • 使用邻接表 + 二叉堆 O(ElogV)O(E log V)
  • 使用斐波那契堆可优化至 O(E+VlogV)O(E + V log V)

code

cpp
void prim(){
    priority_queue<pair<int,int>,vector<pair<int,int>>,greater<pair<int,int>>> q;
    memset(dis,0x3f,sizeof(dis));
    dis[1]=0;
    q.push({0,1});
    while(!q.empty()&&cnt<n){
        int d=q.top().first,u=q.top().second;q.pop();
        if(vis[u]) continue;
        vis[u]=1;
        sum+=d;
        cnt++;
        for(int i=head[u];i;i=E[i].nxt){
            int v=E[i].to,w=E[i].w;
            if(w<dis[v]) dis[v]=w,q.push({w,v});
        }
    }
}

例子

text
     2
 A ----- B
 |      |
3|      |1
 |      |
 C ----- D
     4

从A开始

  • 选边 (A,B,2),加入 B
  • 选边 (B,D,1),加入 D
  • 选边 (A,C,3),加入 C MST总权重 2+1+3=62 + 1 + 3 = 6

Kruskal

加边法

将所有边按权重从小到大排序,每次选择一条最小的边,如果加入这条边不会形成环,就将其加入生成树。

算法步骤

  1. 将图中所有边按权重从小到大排序。
  2. 初始化一个空的最小生成树。
  3. 按权重从小到大遍历每条边(如果当前边连接的两个顶点不在同一个连通分量中(即加入后不会形成环),则将该边加入生成树,并合并这两个连通分量)
  4. 直到生成树中有V−1V-1条边为止。

实现关键

  • 使用并查集数据结构来高效地判断是否形成环(即检查两个顶点是否属于同一集合)。
  • 需要对所有边进行排序。

时间复杂度

  • 排序边 O(ElogE)O(E log E)
  • 并查集操作(路径压缩+按秩合并)近似 O(α(V))O(α(V)),几乎为常数
  • 总复杂度 O(ElogE)O(E log E)O(ElogV)O(E log V)(因为E最多为V²)

code

cpp
int fa[N],n,m;       //用来实现并查集,记录每个顶点的祖宗顶点
struct Edge{
    int a,b,w;
    friend bool operator < (Edge a,Edge b){
        return a.w<b.w;
    }
}E[M];
int find(int u){//寻找祖宗顶点,并且路径压缩
    if(u==p[u]) return u;
    return p[u]=find(p[u]);
}
int kruskal(){
    sort(E,E+m);        //将边按照边权大小排序
    iota(fa+1,fa+n+1,1);//对fa[]数组初始化,一开始每个顶点的祖宗都是自己
    int sum=0,cnt=0;      //记录最后的答案,即最小生成树的所有边的边权;记录连通部分有多少边,方便最后判断图是否连通
    for(int i=0;i<m;i++){//遍历每一条边
        int a=E[i].a,b=E[i].b,w=E[i].w;
        a=find(a),b=find(b);        //找到边的两个顶点的祖宗(看俩个顶点是否属于一个集合)
        if(a!=b){//如果祖宗不同,也就是不在一个集合
            sum+=w;
            cnt++;      //连通部分的边数加一
            p[a]=b;     //把a的祖宗置为b
        }
    }
    if(cnt<n-1) return 0x3f3f3f3f;//如果最后连通部分的边数小于n-1,就说明图不连通
    else return res;
}

例子

text
     2
 A ----- B
 |      |
3|      |1
 |      |
 C ----- D
     4

边排序后(B,D,1), (A,B,2), (A,C,3), (C,D,4)

  • 选(B,D,1),无环,加入
  • 选(A,B,2),无环,加入
  • 选(A,C,3),无环,加入
  • 已选3条边(V=4,边数已够),停止。MST总权重 1+2+3=61+2+3=6

对比

特性Prim算法Kruskal算法
核心思想加点(从一点开始扩张)加边(按权重从小到大选)
数据结构优先队列并查集、需排序所有边
时间复杂度O(ElogV)O(E log V)O(ElogE)O(E log E)
适用图稠密图(边多顶点少)稀疏图(边少顶点多)
过程特点始终维护一棵连通的树中间过程可能是多棵树的森林
起始点需要指定一个起始点不需要起始点,全局考虑边