首页 > 代码库 > 口袋的天空

口袋的天空

题目描述

给你云朵的个数N,再给你M个关系,表示哪些云朵可以连在一起。 现在小杉要把一些云朵连在一起,做成K个棉花糖,一个棉花糖最少要用掉一朵云,小杉想知道他怎么连,花费的代价最小。

输入

每组测试数据的 第一行有三个数N,M,K(1< =N< =1000,1< =M< =10000,1< =K< =10) 接下来M个数每行三个数X,Y,L,表示X云和Y云可以通过L的代价连在一起。(1< =X,Y< =N,0< =L< 10000) 30%的数据N< =100,M< =1000

输出

对每组数据输出一行,仅有一个整数,表示最小的代价。 如果怎么连都连不出K个棉花糖,请输出‘No  Answer‘。

样例输入

3 1 2
1 2 1

样例输出

1

这一道题目大意就是说,原来要的是一颗生成树,现在要K棵。我们可以大胆猜想一下,如果一颗生成树连通至少需要N-1条边,那么两棵生成树的生成只需要N-2边,原因就是我们可以把原来一棵生成树中的任意一条边删去,这样就又有了一棵生成树。所以,要生成K个生成树,我们只需要连通N-K条边,就可以了。

技术分享
 1 #include <cmath>
 2 #include <cstdio>
 3 #include <cstring>
 4 #include <iostream>
 5 #include <algorithm>
 6 
 7 using namespace std;
 8 
 9 struct node
10 {
11     int u,v,cost;    
12 };
13 
14 node a[100005];
15 int f[100005];
16 int N;
17 int Len=0;
18 
19 bool cmp(node i,node j)
20 {
21     return i.cost < j.cost;
22 }
23 
24 int find(int X)
25 {
26     if (f[X] != X) f[X]=find(f[X]);
27     return f[X];
28 }
29 
30 int main()
31 {
32     int M,K;
33     scanf("%d%d%d",&N,&M,&K);
34     for (int i=1; i<=N; i++)
35     {
36         f[i]=i;
37     }
38     for (int i=1; i<=M; i++)
39     {
40         scanf("%d%d%d",&a[i].u,&a[i].v,&a[i].cost);
41     }
42     int ans=0; int total=0;
43     sort(a+1,a+M+1,cmp);
44     for (int i=1; i<=M; i++)
45     {
46         int fx=find(a[i].u);
47         int fy=find(a[i].v);
48         if (fx > fy) swap(fx,fy);
49         if (fx == fy) continue;
50         if (fx != fy)
51         {
52             f[fy]=fx;
53             ans+=a[i].cost;
54             total++;
55             if (total == N - K) break;
56         }
57     }
58     if (total < N - K) printf("No Answer\n");
59     else printf("%d\n",ans);
60 }
Show My Ugly Code

 

口袋的天空