口袋的天空
时间限制: 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个块后输出其花费即可。
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
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 }