最小生成树算法

1.生成树:就是将图删掉一些边,变成树,假定图有n个点,其生成树一定是n-1条边

2.最小生成树:就是指生成树中权值最小的树之和

3.最小生成树算法有两种(Kruskal算法必须掌握

a.prim算法:其算法复杂度为O(n*n),其算法思想与Dijkstra算法类似,算法共分三步:1.选最小  2.标记   3.更新。(他们的区别是d[i]的定义不同)在Dijkstra算法中d[i]表示从起点到第i个结点最短路径的长度。在prim算法中与i结点相连的最短的边(除去被别的点抢先占用的边)

b.Kruskal算法:其算法复杂度O(n*logn),其算法核心是排序和并查集,需要重点掌握

4.实例:

#include<bits/stdc++.h>
using namespace std;
struct Edge
{
  int u, v, w;
  Edge(int _u, int _v, int _w):u(_u), v(_v), w(_w)//初始化时u v w 值确定
  {

  }

  Edge()//初始化函数2,初始化时u v w 值不确定
  {

  }
};
Edge e[200005];

//并查集
int father[5005];
int find(int x)//并查集的查找函数
{
    if(father[x]==x)
    {
        return x;
    }
    else
    {
        father[x]=find(father[x]);//递归调用,有路径压缩的并查集
        return father [x];
    }
}

//排序的比较规则
bool comp(const Edge &a,const Edge &b)
{
    if(a.w <b.w)//按边的权值从小到大排序
    {
        return true;
    }
    return false;
}


int main ()
{
   int N,M;
   cin>>N>>M;
   for(int i=1;i<=N;i++)
   {
       father[i]=i;//并查集,父亲表示法
   }

   for(int i=0;i<M;i++)
   {
       int u,v,w;
       cin>>u>>v>>w;
       e[i]=Edge(u,v,w);
   }
   sort(e,e+M,comp);//排序

   int k=0;//边的计数器
   int tot=0;//边的权值的累加器
   for(int i=0;i<M;i++)//依次处理i条边
   {
       if(find(e[i].u) != find(e[i].v))//如果u和v不在同一个集合里
       {
           father[find(e[i].u)]=find(e[i].v);
           tot += e[i].w;//累加权值
           k++;//边数增一
       }
       if(k == N-1)
       {
           break;
       }
   }
   cout<<tot;
    return 0;
}
/*
6
9
1 2 1
1 6 2
2 3 4
2 6 4
3 4 2
3 6 1
4 5 3
4 6 3
5 6 5
*/

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值