一开始先把这n个点 看作是 n 棵树,那么要得到 k 棵树的话我们只需要连 n - k 条边就可以了
大概做法就是: 1.排序:先将所有边 按照权值 从小到大排序; 2.并查集:扫描所有的边,如果这两个点之间不是一棵树的, 那么就连起来; 3.判断:如果到最后 连的边数已经 大于或等于 n - k 了,那么说明可以,否则就不行;
#include<bits/stdc++.h>usingnamespace std;typedeflonglong ll;constint N =1e5+10;int n, m, k;int p[N];int pu, pv;structE{int u, v, w;}e[N];booloperator<(E x, E y){return x.w < y.w;}intfind(int x){return p[x]== x ? x : p[x]=find(p[x]);}intmain(){int ans =0, sum =0;scanf("%d%d%d",&n,&m,&k);for(int i =1; i <= m; i ++)scanf("%d%d%d",&e[i].u,&e[i].v,&e[i].w);for(int i =0; i <= n; i ++) p[i]= i;sort(e +1, e + m +1);for(int i =1; i <= m; i ++){
pu =find(e[i].u), pv =find(e[i].v);if(pu != pv){
p[pu]= pv;
ans += e[i].w;
sum ++;if(sum == n - k){
cout << ans;return0;}}}
cout <<"No Answer";return0;}
口袋的天空边做kru边判断当前是否已经满足有k个连通块#include <bits/stdc++.h>using namespace std;typedef long long ll;const int N = 1e5 + 10;int n, m, k;int p[N];int pu, pv;struct E{ int u, v, w;}e[N];bool operator < (E x, E y){ return x.w < y.w;}int