最小生成树Kruskal算法模板(c/c++)

最小生成树的Kruskal算法网上的介绍层出不穷。
个人理解:在不构成回路的情况下,优先选择最短的边,若有n个点,则选择n-1条边
下面是模板 参照例题 “”“公路村村通”或者 hdu1863

公路村村通

#include"iostream"
#include"algorithm"
using namespace std;
int f[1009]; int s=0;
int chang=0;
struct node{
int from,to;
long long len;
} pp[3009];
bool comp(struct node a,struct node b){
    return a.len<b.len;
}
void init(int n){
    for(int i=1;i<=n;i++){
        f[i]=i;
    }
    return;
}
int Find(int x){
    if(f[x]==x) return f[x];
    else{
        return f[x]=Find(f[x]);
    }
}
bool same(int x,int y){
    int f1=Find(x);
    int f2=Find(y);
    return f1==f2;
}
void Merge(int x,int y){
    int f1=Find(x);
    int f2=Find(y);
    if(f1!=f2)
    {
        f[f2]=f1;
    }
    return;
}
int main(){//从main开始读程序是个好习惯
    int n,m;  
    int a,b,c;
    cin>>n>>m;
    init(n);//初始化
    for(int i=1;i<=m;i++){//输入 写的复杂啦哈
        cin>>a>>b>>c;
        pp[i].from=a;
        pp[i].to=b;
        pp[i].len=c;
   }
   std::sort(pp+1,pp+1+m,comp);//排序 自定按边长短 从小到大排序
   for(int i=1;i<=m;i++){
       if(s==n-1) break;//已经选了n-1条边跳出
       if(same(pp[i].from,pp[i].to)) continue;//两个点在一个集合中
       Merge(pp[i].from,pp[i].to);//合并两个点
       chang+=pp[i].len;//长度累加
       s+=1;//条数累加
   }
   if(s==n-1)
   cout<<chang<<endl;
   else//不满足
   cout<<-1<<endl;
    return 0;
}

@[TOC](

你可能感兴趣的:(并查集)