MSTkruskal算法的理解

伪代码:

把所有边排序,记第i小的边为e[i](1<=i<m)

初始化MST为空

初始化联通分量,让每个点自成一个独立的联通分量

for(int i = 0;i < m;i++)

if(e[i].u和e[i].v不在同一个联通分量)

{

把边e[i]加入MST

合并e[i].u和e[i].v的联通分量

}

首先把所有边按照权值排序,找到最小的权值所在的边,用这些点构造联通图可以保证图的权值最小。然后依次搜索,每次都找到下一个最小的点,如果这些点已经包含在联通图里,说明我们如果现在把它们放进去,图的权值会大于我们之前已经构建的图,不符合题意。所以只添加没有包含的点。如此扫描下去直到把所有点加进去,因为每个点加进去的都是最小权值,所以图的权值最小,也叫最小生成树(MST)

下一个关键问题是合并:合并的最简单表示方式是用并查集。用树表示集合。把点x的父节点保存在p[x]中(如果没有父节点,p[x]=x)。所以找出节点所在树的递归程序是:

int find(int x){p[x] == x?x:p = find(p[x]);}返回x所在的树根。

代码:int cmp(const int i,const int j){return w[i] < w[j];}//间接排序函数

int find(int x){return p[x] == x?x:p = find(p[x]);}//查找结点的树根

int Kurskal()

{

    int ans = 0;

    for(int i = 0;i < n;i++) p[i]=i;

    for(int i = 0;i < m;i++) r[i]=i;

    sort(r,r+m,cmp);

    for(int i = 0;i < m;i++)

      { int e=r[i];int x = find(u[e]);int y = find(v[e]);

       if(x != y){ans += w[e];p[x]=y;}//不在同一个集合,合并

    return ans;

}

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值