Prim堆优化

介绍

Prim 算法是求解最小生成树的经典算法之一。

它和 Kruskal 一样,都是基于贪心思想的最小生成树算法。

不同的是:

  • Kruskal 是从边的角度出发,每次选择当前最小且不成环的边
  • Prim 是从点的角度出发,每次选择距离当前生成树最近的点

堆优化 Prim 通常使用优先队列维护当前距离生成树最近的点,写法和 Dijkstra 很像,时间复杂度为 O(mlog⁡n)。

知识点

  • Prim 算法是一种基于顶点扩展的最小生成树贪心算法
  • 堆优化 Prim 使用优先队列维护距离当前生成树最近的点
  • 每次从堆中取出距离最小的未加入点
  • 加入新点后,用它的所有邻边更新其他点到生成树的最小距离
  • 如果最终没有加入所有点,说明原图不连通,不存在最小生成树
  • 堆优化 Prim 的时间复杂度为 O(mlog⁡n)

核心思想

Prim 算法的核心思想是:

当前已经有一棵生成树,每次选择一条连接"树内点"和"树外点"的最小边,把新的点加入生成树。

一开始,生成树中只有一个起点。

之后每次从所有可以连接到树外点的边中,选择权值最小的一条。

这条边连接的树外点会被加入生成树。

不断重复这个过程,直到所有点都被加入。

堆优化 Prim 中,我们用优先队列维护这些候选点,每次快速取出距离当前生成树最近的点。

算法步骤

  1. 建立无向图。

  2. 初始化 dist 和 vis 数组。

  3. 从 1 号点开始,将 (0, 1) 加入优先队列。

  4. 每次从优先队列中取出边权最小的点 u。

  5. 如果 u 已经加入生成树,就跳过。

  6. 否则把 u 加入生成树,并累加答案。

  7. 用 u 的所有邻边更新其他点。

伪代码

复制代码
function Prim_Heap(G, n):
    dist[n+1] = INF
    vis[n+1] = false
    dist[1] = 0
    priority_queue pq
    pq.push((0, 1))
    ans = 0
    cnt = 0
    
    while pq不为空 and cnt < n:
        (d, u) = pq.top()
        pq.pop()
        if vis[u]: continue
        vis[u] = true
        ans += d
        cnt++
        
        for 每个邻接顶点v和边权w:
            if not vis[v] and w < dist[v]:
                dist[v] = w
                pq.push((w, v))
    
    if cnt == n: 返回ans
    else: 返回"impossible"
相关推荐
微尘hjx26 分钟前
【ByteTrack 04】多轨迹算法ByteTrack改进点
算法·yolo·目标检测·目标跟踪·bytetrack·ultralytics·车跟踪
路灯上の马陈2 小时前
二叉树的定义与性质
数据结构·二叉树·树结构·1024程序员节
小蒋观天下4 小时前
雷击与浪涌防护:前端SPD选型、接地网误区,接地不当反而引入干扰
深度学习·算法·机器学习
Bshaya_5 小时前
红黑树详解:概念、规则与插入实现
数据结构·红黑树·二叉搜索树·平衡树·插入逻辑
WBluuue6 小时前
数据结构与算法:分块(一):块状数组、块状链表
数据结构·c++·算法·链表
路灯上の马陈7 小时前
数据结构-树
数据结构·1024程序员节
澳鹏Appen7 小时前
澳鹏重磅发布ExamOCRBench:面向端到端试卷判分的多任务基准
算法·benchmark·基准评测
benjormin7 小时前
Java数据结构 二叉搜索树
数据结构·算法
人工智能培训7 小时前
知识图谱:结构化表达实体与关系的知识组织技术
大数据·人工智能·算法·重构·生活·知识图谱