Kruskal最小生成树

废话

本篇博客只是复习记录所用,有任何不足之处,欢迎指出

正篇

1.自己的一些感悟

不同于Prim算法每次加入一个点,直到所有的点加入到同一集合生成一颗最小树,kruskal是每次寻找最小的边,同时记录加入的点,直到加入的点的数量和顶点数一样,本质上都是寻找先寻找拥有最小权值的边,prim是从起始点开始,而kruskal直接从边开始。

2.算法思想

在这里插入图片描述

3.伪代码描述

在这里插入图片描述

4.模拟

在这里插入图片描述
第一步:初始化连通分量,每一个顶点都是一个连通分量,相互独立。

在这里插入图片描述
第二步:从当前权值最小的边出发,找到这条边的两个顶点的同时判断这个顶点是否为一个连通分量,如果是不是连通分量,那就将两个顶点并在一起,如果是,则不用处理。最后将这条边进行标记。

在这里插入图片描述
接下来不断重复第二步就可以了,直到所有的边都遍历完或者顶点加入的数量和图中顶点数相同。
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

代码

#include<iostream>
#include<cstring>
#include<algorithm>
using namespace std;

const int Size = 100;
int parent[Size];

struct Edge
{
    int from,to;
    int info;
};

struct Graph
{
    int vertex[Size];
    Edge bian[Size];
    int verNum,arcNum;
};

void Kruskal(Graph p);
int FindRoot(int parent[],int v);

main()
{
    struct Graph p;
    int i,j,k;
    cin>>p.verNum>>p.arcNum;
    for(i = 0;i < p.verNum;i ++){
        p.vertex[i] = i;
    }

    for(i = 0;i < p.arcNum;i ++){
        cin>>p.bian[i].from>>p.bian[i].to>>p.bian[i].info;
    }
    Kruskal(p);

    return 0;

}

void Kruskal(Graph p)
{
    int num,i,j,vex1,vex2,ans;
    memset(parent,-1,sizeof(parent));

    for(i = 0;i < p.arcNum;i ++){          //根据边集的权值由小到大排序
         for(j = i;j < p.arcNum;j ++)
          {
                if(p.bian[i].info > p.bian[j].info)
                {
                    Edge tem = p.bian[i];
                    p.bian[i] = p.bian[j];
                    p.bian[j] = tem;
                }
          }
    }

    for(num = 0,i = 0;i < p.arcNum;i ++)
    {
        vex1 = FindRoot(parent,p.bian[i].from);    //找到根节点
        vex2 = FindRoot(parent,p.bian[i].to);
        if(vex1 != vex2)    //判断是否为同一连通分量
        {
            cout<<"("<<p.bian[i].from<<","<<p.bian[i].to<<")"<<"   ";
            parent[vex2] = vex1;     //将vex2的上一节点设置为 vex1
            num ++;
            if(num == (p.verNum - 1)) break;
        }
    }
}


int FindRoot(int parent[],int v)   //寻找根节点
{
   int t = v;
   while(parent[t] != -1)
   {
       t = parent[t];
   }
   return t;
}




/*
6 10
1 2 6
1 3 1
1 4 5
2 3 5
3 4 5
2 5 3
5 3 6
3 6 4
6 4 2
5 6 6

(1,3)(3,6)(6,4)(3,2)(2,5)
*/

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值