觉得这里讲得挺详细的,大家可以去看
Kruskal算法详解
它和Prim算法和Boruvka算法等。三种算法都是贪心算法的应用。
算法思想
从G中选择一条当前未选择过的、且边上的权值最小的边加入TE,若加入TE后使得T未产生回路,则本次选择有效,如使得T产生回路,则本次选择无效,放弃本次选择的边。重复上述选择过程直到TE中包含了G的n-1条边,此时的T为G的最小生成树。
对比两个算法,Kruskal算法主要是针对边展开,边数少时效率会非常高,所以对稀疏图有很大的优势;Prim算法对于稠密图,即边数非常多的情况会好一些
#include<stdio.h>
#include<iostream>
#include<algorithm>
using namespace std;
const int M = 1e5+7;
struct node{
int a,b,val;
} Q[M];
int fa[M];
int Rd(){
int res=0;
char c;
while(c=getchar(),!isdigit(c));
do {
res=(res<<3)+(res<<1)+(c^48);
} while(c=getchar(),isdigit(c));
return res;
}
bool cmp(LZ a,LZ b){
return a.val<b.val;}
int getfa(int v){
if(fa[v]!=v)fa[v]=getfa(fa[v]);
return fa[v];}
int main(){
int i,j,n,m,x,y;
scanf("%d%d",&n,&m);
for(i=1;i<=m;i++) {
Q[i].a=Rd();Q[i].b=Rd();Q[i].val=Rd();
}
sort(Q+1,Q+m+1,cmp);
for(i=1;i<=n;i++) {
fa[i]=i;
}
int sum=0,cut=0;
for(i=1;i<=m;i++) {
x=getfa(Q[i].a);
y=getfa(Q[i].b);
if(x==y)continue;
sum+=Q[i].val;
if(++cut==n-1)break; fa[x]=y; } printf("%d",sum); return 0;}