生成树算法总结(Prim,Kruskal,Boruvka)

前言

其实原理都很简单

Prim

指定一个点作为原点 s s s 向外不断连边
时间复杂度:手写堆 O ( m l o g n ) O(mlogn) O(mlogn) STL m l o g m mlogm mlogm 斐波那契堆 O ( n l o g n + m ) O(nlogn+m) O(nlogn+m)

Kruskal

按边权连边,并查集实现
时间复杂度: O ( m l o g m ) O(mlogm) O(mlogm)

Boruvka

多点合并,每个连通块选择最短的边往外连最短的边
时间复杂度 O ( m l o g n ) O(mlogn) O(mlogn)

struct Edge{
	int u,v,w;
}edge[MAXM+5];
int mst,fa[MAXN+5],cho[MAXN+5];
inline int Find(int x){return (x==fa[x]?x:(fa[x]=Find(fa[x])));}
void Boruvka(int N,int M){
	int bcnt=N;
	for(int i=1;i<=N;i++)
		fa[i]=i;
	while(bcnt>1){
		memset(cho,-1,sizeof(cho));
		for(int i=1;i<=M;i++){
			int fu=Find(edge[i].u),fv=Find(edge[i].v);
			if(fu==fv) continue;
			if(cho[fu]==-1||edge[cho[fu]].w>edge[i].w)
				cho[fu]=i;
			if(cho[fv]==-1||edge[cho[fv]].w>edge[i].w)
				cho[fv]=i;
		}
		for(int i=1;i<=N;i++){
			if(cho[i]==-1) continue;
			int fu=Find(edge[cho[i]].u),fv=Find(edge[cho[i]].v);
			if(fu==fv) continue;
			bcnt--,fa[fv]=fu;
			mst+=edge[cho[i]].w;
		}
	}
	return ;
}

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值