最小生成树基本算法---算法导论读书笔记

本文介绍了最小生成树(Minimum Spanning Tree, MST)的概念及其在最优化问题中的应用,重点关注Kruskal和Prim两种经典算法。Kruskal算法适合稀疏图,Prim算法适用于稠密图,两者都是贪心策略,每步添加安全边。在实际问题中,如考虑全局优化和连通性时,MST是一个有效的解决方案。" 112719533,10293923,图文详情页秒开实践:今日头条白屏优化与性能提升,"['前端开发', '移动开发', '性能优化', 'Android开发', 'iOS开发']

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

    首先谈下对最小生成树(Minimum Spanning Tree, MST)用处的理解,然后给出经典的Kruskal和Prim算法的伪码和理解。


    首先显然它是解决最优化问题的,用的是贪心的思想(于是显然它是非常“优”的了,能用它解决就用它吧)。

    最小生成树是从一个图简化而来,保留所有的(从树的角度来讲是连通图的所有)顶点以及连通性,砍掉尽可能多的边并使得剩下的边权值的和最小(用最短的边保持连通性)。

    映射到现实问题,当我们面对一些有关系的实体(比如一个实体可以导出另一个实体),我们不愿丢掉连通性(砍掉两点之间的边一定是在有其它路径存在的前提下),希望获得最小代价的时候,可以考虑最小生成树。它与单源最短的区别就在于,第一它是全局的一种优化,没有指定的起点,不是针对某个特定的实体对其他的实体关系的问题;第二它多条边组成的路径对两端的点来说未必是最短的,但是它每条边对于两边的集合来说是最短的,单源最短路具有最优子结构,也就是说,单源最短路生成的图中,只要源点不作为中点,任意两点之间的路径一定是最短路。

    最小生成树总的贪心思路是:每一步加入一条安全边。Kruskal和Prim以不同的方式寻找安全边。

    说明一些术语:

        安全边:不妨碍最小生成树边集的一条割的轻边。

        割:把顶点分成两个集合,把相连的边剪掉。宛如一把剪刀。

        不妨碍:A是一个边的集合,A中没有边通过割B,就说割B不妨碍边集A。

        轻边:最小权值边。


 Kruskal:

 MST-KRUSKAL(G,w)

 

//initial
A <- empty
for each vertex v from V[G]
     do MAKE-SET(v)
//add safe edge to form tree
sort the edges of E into nondecreasing order by weight w
for each edge(u,v) from E
   do if FIND-SET(u) != FIND-SET(v)
        then A <- A + {(u,v)}
                UNION(u,v)
return A

    算法思想是维护不想交的元素集合,连接这些集合的边是安全边。一个集合看做一个树,也就是一开始就是把图割成各个顶点独自组成各自树,集合中是当前森林一棵树中的顶点。这个森林没有丢点,但失去了连通性。FIND-SET(u)返回包含u的集合中的一个代表元素,以此对两个点使用可以测试是否在同一个集合,用UNION合并集合。我们不断用最小的边连通原本不连通的集合。

    它的运行时间取决于集合的实现方式。


Prim;

MST-PRIM(G,w,r)

//initial
for each u from V[G]
  do key[u] <- inf //infinity
     pre[u] <- NULL
key[r] <- 0
Q <- V[G]
//add safe edge to form tree
while Q != empty
   do u <- EXTRACT-MIN(Q)
      for each v from Adj[u]
          do if v from Q and w(w,v) < key[v]
                then pre[v] <- u
                     key[v] <- w(u,v)

    算法很像Dijkstra,它本身只找出树不找出整个森林(当然我们可以再外面套一个循环找出森林),不断向集合加入一个离集合最近的点与边,找出连通子集的所有点,在找的过程中就保证了连通性。key[v]代表v到集合轻边的值(没有边则为infinity)。

    性能取决于优先队列Q的实现。


比较:

    Kruskal适合稀疏图,Prim适合稠密图。但它们从渐进意义上好的实现的复杂度是相等的。


习题应用:

    poj1789,poj2485,poj1258,poj3026


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值