口袋的天空
Posted DJY_01
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了口袋的天空相关的知识,希望对你有一定的参考价值。
题目背景
小杉坐在教室里,透过口袋一样的窗户看口袋一样的天空。
有很多云飘在那里,看起来很漂亮,小杉想摘下那样美的几朵云,做成棉花糖。
题目描述
给你云朵的个数 NN ,再给你 MM 个关系,表示哪些云朵可以连在一起。
现在小杉要把所有云朵连成 KK 个棉花糖,一个棉花糖最少要用掉一朵云,小杉想知道他怎么连,花费的代价最小。
输入输出格式
输入格式:
每组测试数据的
第一行有三个数 N,M,K(1 \le N \le 1000,1 \le M \le 10000,1 \le K \le 10)N,M,K(1≤N≤1000,1≤M≤10000,1≤K≤10)
接下来 MM 个数每行三个数 X,Y,LX,Y,L ,表示 XX 云和 YY 云可以通过 LL 的代价连在一起。 (1 \le X,Y \le N,0 \le L<10000)(1≤X,Y≤N,0≤L<10000)
30\%30% 的数据 N \le 100,M \le 1000N≤100,M≤1000
输出格式:
对每组数据输出一行,仅有一个整数,表示最小的代价。
如果怎么连都连不出 KK 个棉花糖,请输出‘No Answer‘。
输入输出样例
3 1 2 1 2 1
1
所以我们如果想要连出k棵树,就需要连n-k条边。题目要求用n朵云连出k个棉花糖。
因为每个棉花糖都是连通的,那么每个棉花糖就相当于是一棵树。
就是说要用n个节点连出k棵树。也就是说要用n-k条边连出k棵树。
也就是说要花费连出n-k条边的代价。既然一定要花费连出n-k条边的代价,
那么当然要选择代价最小的边连起来。所以给每条可以连的边按代价从小到大排个序,
然后输出就可以了。
代码:
// luogu-judger-enable-o2 #include<iostream> #include<algorithm> using namespace std; struct stu { int x,y,z; bool operator < (stu h) const { return z<h.z; } }a[110000]; int n,m,k; int fa[1100000],sum=0,ans=0; int f(int x) { if(fa[x]==x) return x; else return fa[x]=f(fa[x]); } int bing(int x,int y,int z) { int tx=f(x),ty=f(y); if(tx!=ty) { fa[tx]=ty; sum++; ans+=z; } return sum; } int main() { int x,y,z; cin>>n>>m>>k; for(int i=1;i<=n;i++) fa[i]=i; for(int i=1;i<=m;i++) cin>>a[i].x>>a[i].y>>a[i].z; sort(a+1,a+m+1); for(int i=1;i<=m;i++) { sum=bing(a[i].x,a[i].y,a[i].z); if(sum==n-k) { cout<<ans; return 0; } } cout<<"No Answer"; }
以上是关于口袋的天空的主要内容,如果未能解决你的问题,请参考以下文章