口袋的天空

口袋的天空

时间限制: 1 Sec  内存限制: 128 MB
提交: 104  解决: 55
[提交][状态][讨论版]

题目描述

给你云朵的个数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

提示

样例2: Input: 3  1  1 1  2  1 Output: No  Answer

题解:这道题就是让你用边将白云连起来,然后剩下k个块,这样便想到了kruskal算法,prim算法不行,因为剩下k个快的最小花费,可以分为不同几个联通块,而一个大块和几个大小为一的块时费用不为最小,所以要用kruskal才行,剩下k个块后输出其花费即可。

 1 #include<cstdio>
 2 #include<algorithm>
 3 #include<iostream>
 4 #include<cmath>
 5 #include<cstring>
 6 #include<string>
 7 
 8 using namespace std;
 9 const int MAXN=10007;
10 
11 struct fzy
12 {
13     int u,v,zhi;
14 }a[MAXN];
15 int num,n,m,k;
16 int f[1007];
17 
18 void init()
19 {
20     num=0;
21     for (int i=0;i<1007;i++)
22         f[i]=i;
23 }
24 bool cmp(fzy a,fzy b)
25 {
26     return a.zhi<b.zhi;
27 }
28 int find(int num)
29 {
30     if (f[num]!=num) f[num]=find(f[num]);
31     return f[num];
32 }
33 int main()
34 {
35     init();
36     
37     int x,y,z;
38     scanf("%d%d%d",&n,&m,&k);
39     if (n<k)
40     {
41         printf("No Answer");
42         return 0;
43     }
44     if (n==k)
45     {
46         printf("0");
47         return 0;
48     }
49     for (int i=1;i<=m;i++)
50     {
51         scanf("%d%d%d",&x,&y,&z);
52         a[++num].u=x;
53         a[num].v=y;
54         a[num].zhi=z;
55     }
56     sort(a+1,a+num+1,cmp);
57     int number=0,ans=0;
58     for (int i=1;i<=num;i++)
59     {
60         x=find(a[i].u),y=find(a[i].v);
61         if (x!=y)
62         {
63             number++;
64             ans+=a[i].zhi;
65             f[y]=x;
66         }
67         if (number==n-k) break;
68     }    
69     printf("%d",ans);
70 }
View Code
原文地址:https://www.cnblogs.com/fengzhiyuan/p/6941984.html