最小生成树算法——Prim

简介: 最小生成树算法——Prim


P算法流程

一开始图中所有的边都默认被锁住了,只有边被解锁了,才能考虑要不要这条边。一开始图中所有的点也都默认全部被锁住了,只有选中了某个点,这个点才被解锁,并且这个点的直接边(从这个点出发的边)也全部被解锁。解锁的点放入一个集合。

所以,一开始从图中任意一点出发,在这个点的所有直接边里选一条权值最小的边,如果这条边的的两侧有新结点,就解锁这个结点;如果没有新结点,就不要这条边。然后新解锁的结点的直接边又全部被解锁了,再在这些边里面选权值最小的边…周而复始。

总的来说,P算法流程就是,先从某个点出发,解锁一批边,选条最小的边解锁一个新结点,再解锁一批边…

P算法不需要用到并查集,因为总是一个点解锁一批边,在这一批边里选一个点放入集合里。每次都是一个一个点进入集合,根本不存在两大片集合要合并的问题。所以表示解锁的点只需要一个集合就可以。当然边的选择还是要用到小根堆。

大家可以按照上面的思路和下面图片来理一下思路:

image.png

package com.harrison.class11;
import java.util.Comparator;
import java.util.HashSet;
import java.util.PriorityQueue;
import java.util.Set;
import com.harrison.class11.Code01_NodeEdgeGraph.*;
public class Code06_Prim {
  public static class EdgeComparator implements Comparator<Edge>{
    public int compare(Edge e1,Edge e2) {
      return e1.weight-e2.weight;
    }
  }
  public static Set<Edge> primMST(Graph graph){
    // 按边的权值组织的小根堆
    PriorityQueue<Edge> pq=new PriorityQueue<>(new EdgeComparator());
    // 解锁的点放入这个集合里
    HashSet<Node> nodeSet=new HashSet<>();
    // 保证放入小根堆里的边不会重复
    HashSet<Edge> edgeSet=new HashSet<>();
    // 选好的边就依次放入这个集合
    Set<Edge> ans=new HashSet<>();
    // for循环只是为了防止森林的出现,也可以去掉此for循环
    // 因为面试题中不会出现森林,不管有向无向
    for(Node node:graph.nodes.values()) {
      if(!nodeSet.contains(node)) {
        nodeSet.add(node);
        for(Edge edge:node.edges) {// 接下来由这个点解锁一批边
          if(!edgeSet.contains(edge)) {
            pq.add(edge);
            edgeSet.add(edge);
          }
        }
        while(!pq.isEmpty()) {
          Edge edge=pq.poll();// 弹出权值最小的边
          Node toNode=edge.to;
          if(!nodeSet.contains(toNode)) {
            nodeSet.add(toNode);
            ans.add(edge);
            for(Edge nextEdge:node.edges) {
              if(!edgeSet.contains(nextEdge)) {
                pq.add(nextEdge);
                edgeSet.add(nextEdge);
              }
            }
          }
        }
      }
      break;
    }
    return ans;
  }
}

最后再总结一下:

1)随便选一个结点解锁,相邻的边也全部解锁,然后选一条权值最小的边

2)新解锁的边两侧有新结点,则把新节点给解锁,并把新解锁的边考虑在最小生成树里面;新解锁的边两侧没有新结点,则不将新解锁的边考虑在最小生成树里面

3)新解锁的结点所有相邻的边被解锁,已经被考虑在最小生成树里的边不重复解锁,然后在所有相邻的边里选择一条权值最小的边,重复步骤 2)周而复始,一直到把所有的点都解锁完


相关文章
|
19天前
|
算法 索引
class061 最小生成树【算法】
class061 最小生成树【算法】
55 0
|
8月前
|
算法
最小生成树算法:Prim算法
在图论中,最小生成树(Minimum Spanning Tree,简称MST)是一种常用的算法问题。最小生成树是指在一个加权连通图中选取边的子集,使得所有顶点都被覆盖,并且边的总权值最小。
167 0
|
19天前
|
人工智能 算法
一些算法的复习(最短路径、最小生成树、dp)
一些算法的复习(最短路径、最小生成树、dp)
|
19天前
|
算法
最小生成树算法
最小生成树算法
|
19天前
|
存储 机器学习/深度学习 算法
上机实验三 图的最小生成树算法设计 西安石油大学数据结构
上机实验三 图的最小生成树算法设计 西安石油大学数据结构
22 1
|
19天前
|
算法 Java C++
第十四届蓝桥杯集训——练习解题阶段(无序阶段)-ALGO-6 算法训练 安慰奶牛 最小生成树
第十四届蓝桥杯集训——练习解题阶段(无序阶段)-ALGO-6 算法训练 安慰奶牛 最小生成树
26 0
|
7月前
|
算法 C++
用prim和kruskal算法求最小生成树问题
用prim和kruskal算法求最小生成树问题
48 0
|
19天前
|
算法 数据安全/隐私保护 计算机视觉
基于二维CS-SCHT变换和LABS方法的水印嵌入和提取算法matlab仿真
该内容包括一个算法的运行展示和详细步骤,使用了MATLAB2022a。算法涉及水印嵌入和提取,利用LAB色彩空间可能用于隐藏水印。水印通过二维CS-SCHT变换、低频系数处理和特定解码策略来提取。代码段展示了水印置乱、图像处理(如噪声、旋转、剪切等攻击)以及水印的逆置乱和提取过程。最后,计算并保存了比特率,用于评估水印的稳健性。
|
4天前
|
机器学习/深度学习 算法 数据安全/隐私保护
基于DCT变换和位平面分解的数字水印嵌入提取算法matlab仿真
这是一个关于数字水印算法的摘要:使用MATLAB2022a实现,结合DCT和位平面分解技术。算法先通过DCT变换将图像转至频域,随后利用位平面分解嵌入水印,确保在图像处理后仍能提取。核心程序包括水印嵌入和提取,以及性能分析部分,通过PSNR和NC指标评估水印在不同噪声条件下的鲁棒性。
|
5天前
|
算法 数据安全/隐私保护 C++
基于二维CS-SCHT变换和扩频方法的彩色图像水印嵌入和提取算法matlab仿真
该内容是关于一个图像水印算法的描述。在MATLAB2022a中运行,算法包括水印的嵌入和提取。首先,RGB图像转换为YUV格式,然后水印通过特定规则嵌入到Y分量中,并经过Arnold置乱增强安全性。水印提取时,经过逆过程恢复,使用了二维CS-SCHT变换和噪声对比度(NC)计算来评估水印的鲁棒性。代码中展示了从RGB到YUV的转换、水印嵌入、JPEG压缩攻击模拟以及水印提取的步骤。