#include <iostream>
#include <algorithm>
using namespace std;
int r[100],//边的编号 对之排序
w[100],//对应编号边的权值
s[100],//对应边的起始端点
e[100],//对应边的结束端点
p[100],//并查集
n; //边的数量,点从0开始
int cmp(int i,int j) {return w[i]<w[j];}
void read()
{
cin>>n;
for(int i=0;i<100;++i)
{
r[i]=i;//初始化边的序号
p[i]=i;//并查集初始,每一条边自成一个连通区域
//代表元为其本身
}
for(int i=0;i<n;++i)
{
cin>>s[i]//端点1
>>e[i]//端点2
>>w[i];//权值
}
sort(r,r+n,cmp);
}
int find_head(int a) {return p[a]==a?a:p[a]=find_head(p[a]);}
int Kruskal()
{
int ans=0;
for(int i=0;i<n;++i)
{
int t=r[i]; //取得第i+1小的边的编号
int x=find_head(s[t]); //取得该边的端点1的代表元
int y=find_head(e[t]); //取得该边的端点2的代表元
if(x!=y)//不属于同一连通区域
{
ans += w[t];//如未成环加入权值
p[x]=y; //s(t)所属连通区域与e(t)合并,即代表元相同
}
}
return ans;
}
int main()
{
read();
int ans=Kruskal();
for(int i=0;i<n;++i)
cout<<r[i]<<" "<<s[r[i]]<<" "<<e[r[i]]<<" "<<w[r[i]]<<endl;
cout<<ans;
return 0;
}
入门经典-最小生成树代码与注释
最新推荐文章于 2024-07-11 21:13:07 发布