其实原理都很简单
指定一个点作为原点 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)
按边权连边,并查集实现 时间复杂度: O ( m l o g m ) O(mlogm) O(mlogm)
多点合并,每个连通块选择最短的边往外连最短的边 时间复杂度 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 ; }