#include <iostream>
#include <algorithm>
#include <cstdio>
#include <cstring>
using namespace std;
const int maxn = 2e5 + 10;
int father[maxn];
int n, m;
int cnt;
struct node{//存边
int u, v;
int weight;
}edge[maxn * 2];//双向边,开二倍空间
void addedge(int u, int v, int data) {
edge[cnt].u = u;
edge[cnt].v = v;
edge[cnt++].weight = data;
}
bool cmp(node x, node y) {
return x.weight < y.weight;
}
int find(int x) {//找到 x 的祖先, 并进行路径压缩
int z = x;
while(father[x] != x)
x = father[x];
while(z != x) {
int s = z;
z = father[z];
father[s] = x;
}
return x;
}
void kruskal()
{
int sum = 0, ans = 0;
for(int i = 1; i <= n; i++)
father[i] = i;
for(int i = 0; i < 2 * m; i++) {//遍历所有的边
int fx = find(edge[i].u);
int fy = find(edge[i].v);
if(fx != fy) {//若在不同集合里, 连边
father[fx] = fy;
ans += edge[i].weight;
sum++;
if(sum == n - 1)//n个顶点当连n - 1条边时退出, 此时已构成最小生成树
break;
}
}
if(sum == n - 1)
cout << ans << endl;
else//若连接的边数不为 n - 1, 说明当前图不能形成最小生成树
cout << "orz" << endl;
}
int main() {
ios::sync_with_stdio(false);
cin >> n >> m;
int x, y, data;
for(int i = 1; i <= m; i++) {
cin >> x >> y >> data;//无向图存双向边
addedge(x, y, data);
addedge(y, x, data);
}
sort(edge, edge + 2 * m, cmp);//按边的权值从小到大进行排序
kruskal();
return 0;
}
kruskal
最新推荐文章于 2024-06-15 09:15:00 发布