【luogu P1195 口袋的天空】 题解
题目链接:https://www.luogu.org/problemnew/show/P1195
嗯~我是被题目背景吸引到才做的,想吃棉花糖啦!
话说回来,这道题其实很容易就能想明白,k棵最小生成树。
我们用kruskal的思想,每次连接最小代价的边。假设一开始有n棵树,那么我们每次连接两朵云彩就会减少一棵树。
我们设cnt为生成树的数量,每次连接就会是cnt-1-1-1-1....直到cnt == k,就好啦~
1 #include <iostream> 2 #include <cstdio> 3 #include <algorithm> 4 using namespace std; 5 const int maxn = 100000; 6 7 int n,m,k,fa[maxn],cnt,ans = 0; 8 9 int find(int x) 10 { 11 return fa[x] == x?x:fa[x] = find(fa[x]); 12 } 13 14 struct edge{ 15 int u,v,w; 16 }e[maxn]; 17 18 int cmp(edge a,edge b) 19 { 20 return a.w<b.w; 21 } 22 23 int main() 24 { 25 scanf("%d%d%d",&n,&m,&k); 26 27 for(int i = 1; i <= n; i++) 28 { 29 fa[i] = i; 30 } 31 32 for(int i = 1; i <= m; i++) 33 { 34 int x,y,z; 35 scanf("%d%d%d",&x,&y,&z); 36 e[i].u = x; 37 e[i].v = y; 38 e[i].w = z; 39 } 40 cnt = n; 41 sort(e+1,e+1+m,cmp); 42 43 for(int i = 1; i <= m; i++) 44 { 45 if(cnt <= k) break; 46 47 int x = find(e[i].u); 48 int y = find(e[i].v); 49 if(x!=y) 50 { 51 fa[x] = y; 52 ans += e[i].w; 53 cnt--; 54 } 55 56 } 57 58 if(cnt == k) 59 { 60 printf("%d",ans); 61 return 0; 62 } 63 else 64 { 65 printf("No Answer"); 66 return 0; 67 } 68 }
隐约雷鸣,阴霾天空,但盼风雨来,能留你在此。
隐约雷鸣,阴霾天空,即使天无雨,我亦留此地。
![](https://images.cnblogs.com/cnblogs_com/MisakaAzusa/1169114/o_a0c3752e09f79052b15f108c0cf3d7ca7acbd5b0.gif)