口袋的天空
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了口袋的天空相关的知识,希望对你有一定的参考价值。
题目描述
给你云朵的个数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 }
以上是关于口袋的天空的主要内容,如果未能解决你的问题,请参考以下文章