【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://www.cnblogs.com/MisakaAzusa/p/8671910.html