#include <bits/stdc++.h>
using namespace std;
struct edge{int from,to,cost;}; //起点,终点,权值
edge es[100]; //注意存储方式不是邻接表也不是邻接矩阵
bool cmp(edge a,edge b){ //比较两个结点
if(a.cost<b.cost) return true; //小的优先
else return false; //大的在后
}
int par[100],ranks[100]; //存每点双亲与秩
void init(int n){ //传点数
for(int i=0;i<n;i++){ //遍历
par[i]=i; //每个点都是树根
ranks[i]=0; //秩为0
}
}
int finds(int x){ //找X的树根
if(par[x]==x) return x; //找到根就返回
else return par[x]=finds(par[x]); //找双亲的根并记为双亲
}
bool same(int x,int y){ //判断两个结点是否同根
return par[x]==par[y]; //同根返回1
}
void unity(int x,int y){ //合并两结点
x=finds(x); //找X的根
y=finds(y); //找Y的根
if(x==y) return ; //同根不操作
if(ranks[x]<ranks[y]) //X秩小
par[x]=y; //Y记为X双亲
else{ //Y秩小于等于X秩
par[y]=x; //X记为Y双亲
if(ranks[x]==ranks[y]) //如果同秩
ranks[x]++; //X秩+1
}
}
void solve(){
int v,e,s;cin>>v>>e>>s; //v个点e条边s为起点
for(int i=0;i<e;i++) //逐条边输出起点,终点,花费
cin>>es[i].from>>es[i].to>>es[i].cost;//同上
sort(es,es+e,cmp); //按边权排序
int res=0; //答案初始化为0
init(v); //初始化V个点
for(int i=0;i<e;i++){ //逐条边扫一次
if(!same(es[i].from,es[i].to)){ //起终点不在同一树上
unity(es[i].from,es[i].to); //合并两点
res+=es[i].cost; //答案累加
}
}
cout<<res<<endl; //输出答案
}
int main(){
solve();
return 0;
}
/*
最小生成树(Kruskal)
思路:贪心+并查集
Input
4 4 0
0 1 3
1 2 5
2 3 7
3 0 9
output
15
*/
4图-2最小生成树Kruskal
最新推荐文章于 2019-08-09 01:23:37 发布