prim算法求最小生成树_最小生成树

最小生成树:对于一个连通图,包含所有节点且保持连通,权值之和最小的子图

1.prim(普里姆算法):稠密图表现良好

2.kruskal(克鲁斯卡尔算法):简单图表现良好

1.prim

思路:prim是针对于节点的算法。将整个图分为两个部分:已选择A与未选择B。

在B中任意选取一个初始点之后,A包含初始点,B包含除初始点之外的所有点。此时,开始对点进行重复操作:

  • 选取一个B中的点,此点到A的度最小。
  • 此点从B进入A。

直至所有点从B进入A。

对于稠密图而言,时间复杂度为Ov^2

6c7c94c61a7ebea80942fd1403c6c465.png
稠密连通图

初始状态:A{} B{1,2,3,4,5,6} 权值之和:0

任意选取一点进入A:

A{1} B{2,3,4,5,6} 权值之和:0

开始对点重复操作:

距离A中最近的一点是2

2进入A

A{1,2} B{3,4,5,6} 权值之和:2

距离A中最近的一点是3与5

3进入A

A{1,2,3} B{4,5,6} 权值之和:6

距离A中最近的一点是5

5进入A

A{1,2,3,5} B{4,6} 权值之和:10

距离A中最近的一点是4和6

4进入A

A{1,2,3,4,5} B{6} 权值之和:15

距离A中最近的一点是6

6进入A

A{1,2,3,4,5,6} B{} 权值之和:18

最小生成树的权值之和为18.

2.Kruskal

思路:Kruskal是针对于边的算法。包含贪心与并查集的思想,将所有边分为n部分,每次选择度数最小的一条边。

对于任意一个连通网的最小生成树来说,在要求总的权值最小的情况下,最直接的想法就是将连通网中的所有边按照权值大小进行升序排序,从小到大依次选择。

由于最小生成树本身是一棵生成树,所以需要时刻满足以下两点:

  • 生成树中任意顶点之间有且仅有一条通路,也就是说,生成树中不能存在回路;
  • 对于具有 n 个顶点的连通网,其生成树中只能有 n-1 条边,这 n-1 条边连通着 n 个顶点。

连接n个顶点在不产生回路的情况下,只需要n-1条边。

每次选取最小边时,如果其对于的两个点,拥有同一个father,此边跳过。否则它的两个点对应的点集合并。

例题:1584. 连接所有点的最小费用

给你一个points 数组,表示 2D 平面上的一些点,其中 points[i] = [xi, yi] 。

连接点 [xi, yi] 和点 [xj, yj] 的费用为它们之间的 曼哈顿距离 :|xi - xj| + |yi - yj| ,其中 |val| 表示 val 的绝对值。

请你返回将所有点连接的最小总费用。只有任意两点之间 有且仅有 一条简单路径时,才认为所有点都已连接。

示例 1:

98ad0e111e6c70175b15a0fbf3c9ec6d.png

输入:points = [[0,0],[2,2],[3,10],[5,2],[7,0]]

输出:20

解释:

dcbc5d2e380320d9f2c65e4aa2bd5759.png

我们可以按照上图所示连接所有点得到最小总费用,总费用为 20 。

注意到任意两个点之间只有唯一一条路径互相到达。

示例 2:

输入:points = [[3,12],[-2,5],[-4,1]]

输出:18

示例 3:

输入:points = [[0,0],[1,1],[1,0],[-1,1]]

输出:4

示例 4:

输入:points = [[-1000000,-1000000],[1000000,1000000]]

输出:4000000

示例 5:

输入:points = [[0,0]]

输出:0

提示:

  • 1 <= points.length <= 1000
  • -106 <= xi, yi <= 106
  • 所有点 (xi, yi) 两两不同。

来源:力扣(LeetCode)

链接:https://leetcode-cn.com/problems/min-cost-to-connect-all-points

著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

prim算法:

967482b0db055e5658b59c3e29b477c6.png

对应的执行用时与内存消耗:

b855671f9a4e41b1bdef59e7bf44df4b.png

Kruskal算法:

c1358b55f97995b0e51ee84eb738050c.png

对应的执行用时与内存消耗:

832c40fc03c91a9c2c3b29bc26faf192.png
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值