Kruskal算法
作者:
zzu
,
2024-05-15 21:10:40
,
所有人可见
,
阅读 2
#include <iostream>
#include <algorithm>
using namespace std;
const int M = 200010, N = 200010;
int n, m;
int p[N];
struct Edge
{
int a, b, w;
bool operator< (const Edge &W) const
{
return w < W.w;
}
}edges[N];
// 这里定义了一个名为 operator< 的函数,它是小于比较运算符的重载函数。
// bool:表示这个函数返回一个布尔类型的值,即 true 或 false。
// operator<:这是 C++ 中的小于比较运算符,表示小于关系。
// (const Edge &W):这是函数的参数列表,它接受一个常引用类型的 Edge 对象作为参数。const 关键字表示参数是常量,即在函数内部不会被修改。& 符号表示引用,可以避免对象的复制。
// const:这个关键字表示这个函数不会修改对象的成员变量。这个关键字在函数末尾表示函数本身是常量成员函数,不会修改对象的状态。
// return w < W.w;:这行代码是函数的实现部分。它比较当前对象 Edge 的 w 成员变量和参数 W 的 w 成员变量的大小关系,然后返回比较的结果。这里的 w 是 Edge 类的一个成员变量,表示边的权值。
// 这个函数的作用是用来比较两个 Edge 对象的权值大小,以便在使用排序算法时进行排序或者其他需要比较大小的情况。
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, w;
cin >> a >> b >> w;
edges[i] = {a, b, w};
}
sort(edges, edges + m);// 对所有边权进行排序
for(int i = 1; i <= n; i ++) p[i] = i;//初始化并查集
int res = 0, cnt = 0;
for(int i = 0; i < m; i ++)//从小到大枚举所有边
{
int a = edges[i].a, b = edges[i].b, w = edges[i].w;
a = find(a), b = find(b);//各自的祖宗节点
if(a != b) //不在同意集合 添加同集合里
{
p[a] = b;
res += w;
cnt ++;//加了多少条边
}
}
if(cnt < n - 1) puts("impossible");
else cout << res << endl;
return 0;
}