Kruskal算法
作者:
巷港
,
2022-03-05 16:37:36
,
所有人可见
,
阅读 229
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
const int N = 200010;
int p[N]; //每个集合的祖宗节点
int n,m;
struct Edge //每条边包含两个点和边的权重
{
int a,b,c;
}edge[N];
bool cmp(Edge &A,Edge &B) //重载小于号,便于排序
{
return A.c<B.c;
}
int find(int x) //经典并查集
{
if (p[x]!=x) p[x]=find(p[x]);
return p[x];
}
int main()
{
cin>>n>>m;
for (int i=0;i<m;i++)
{
int a,b,c;
cin>>a>>b>>c;
edge[i]={a,b,c};
}
sort(edge,edge+m,cmp);
for (int i=0;i<m;i++) p[i]=i; //初始化并查集,初始时每个节点是独立的节点
int ans=0,cnt=0;
for (int i=0;i<m;i++)
{
int a=edge[i].a,b=edge[i].b,c=edge[i].c;
if (find(a)!=find(b)) //a和b没有在同一个节点,可以合并
{
ans+=c; //统计最小生成树的权重和
cnt++; //统计最小生成树的节点个数
p[find(a)]=find(b); //合并集合
}
}
if (cnt<n-1) puts("impossible"); //n个节点的最小生成树所含节点为n-1
else cout<<ans<<endl;
return 0;
}