最小生成树的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](