https://www.luogu.com.cn/problem/P3366
/* 1.把边从小到大排序 2.将边从小到大遍历,确认是否能添加 (1)如果边连接的两个点所在的点集(树相同,则跳过) (同一棵树上的两个点连接在一起会产生环,就不是树了) (2)点集不同则连接,之后可以进行相关的记录操作 */ #include <bits/stdc++.h> #define pii pair<int, int> #define pb push_back using namespace std; int n, m; vector<pii> to[5001]; int fa[5001]; struct lin{ int u; int v; int val; }li[200001]; //并查集查询 int ff(int x){ if(fa[x]==0) fa[x] = x; if(fa[x]==x)return x; return fa[x] = ff(fa[x]); } bool cmp(lin a,lin b){ return a.val < b.val; } int main() { scanf("%d%d", &n, &m); for (int i = 1; i <= m; i++) scanf("%d%d%d", &li[i].u, &li[i].v, &li[i].val); sort(li + 1, li + 1 + m, cmp);//把边排序 int ans = 0; int cnt = 0; for (int i = 1; i <= m;i++){ int u = li[i].u; int v = li[i].v; int val = li[i].val; if(ff(u)==ff(v))//如果u,v是同一个分组跳过 continue; fa[ff(v)] = ff(u);//合并u,v所在子树 ans += val;//把边的权值加上 cnt++;//把边数加上 } if(cnt+1!=n) printf("orz");//假如边数+1不为点树,即最后没有构成一颗树 else printf("%d", ans);//否则输出答案 }