图的最小生成树学习笔记

  对一个连通图G=(V,E),每条边到实数R的映射为w,我们可以构造生成树T=(V,E'),其中E'是E的子集,w(T)=w(e1)+w(e2)+...+w(en),ei属于E'。而图的最小生成树问题则是寻找这一系列生成树中,w(T)最小的那棵,即为图的最小生成树MST。
  所有关于最小生成树的算法都涉及贪心算法,即局部最优会得到全局最优。
  算法的中心思想是,去掉MST中的某条边e,MST分成两个部分T1,T2,则T1,T2是由其各自顶点所引导的子图的MST,并且对所有连接T1,T2的边ei,w(e)<=w(ei)。
(1)Prim算法
  从一个顶点开始,依次加入距离当前生成树的最近的点,以及其对应的边。
  dist[i]表示第i个点到当前T的最短边的长度,e(i)表示第i个点连接当前T的最短边。
Procedure PRIM(G,w;T)
dist[1]=0,S=empty,T=empty
for i=2 to n:
    dist[i]=INF
    prev[i]=NONE
while S!=V:
    choose i in V-S such that dist[i] is minimal:
        S=S+{i}
    if i!=1:
        T=T+{e(i)}
    for j in A[i] and in V-S:
        if dist[j]>w(ij):
            dist[j]=w(ij)
            e[j]=e(i,j)
  如果在选择最小的dist[i]时用线性查找,则该算法的复杂度为O(|V|*|V|),而采用以dist为key的priority_queue可以降低算法复杂度。
Procedure PRIM(G,w;T)
dist[1]=0,priority_queue Q=empty,T=empty
for i=2 to n:
    dist[i]=INF
Q.push(1)
while(Q is not empty):
    i=Q.front()
    Q.pop()
    S=S+{i}
    if i!=1:
        T=T+{e(i)}
    for j in A[i] and in V-S:
        if dist[j]>w(ij):
            dist[j]=w(ij)
            e[j]=e(i,j)
  算法的复杂度为O(|V|log|V|)
(2)Kruskal算法
  依次加入当前连接不同块的最短边。确定不同块需要数据结构disjoint set。
Procedure KRUSKAL(G,w;T)
T=empty
for i=1 to n:
    Vi={i}
put E into a priority_queue Q with priority function w
while Q is not emmpty:
    e=Q.front()
    Q.pop()
    u,v is the vertices of e
    find the components Vu and Vv containing u and v
    if Vu!=Vv:
        merge(Vu,Vv)
        T=T+{e}
  算法的复杂度为O(|E|log|E|)
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值