题目背景
小杉坐在教室里,透过口袋一样的窗户看口袋一样的天空。
有很多云飘在那里,看起来很漂亮,小杉想摘下那样美的几朵云,做成棉花糖。
题目描述
给你云朵的个数NN,再给你MM个关系,表示哪些云朵可以连在一起。
现在小杉要把所有云朵连成KK个棉花糖,一个棉花糖最少要用掉一朵云,小杉想知道他怎么连,花费的代价最小。
输入输出格式
输入格式:
每组测试数据的
第一行有三个数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%的数据1000N≤100,M≤1000
输出格式:
对每组数据输出一行,仅有一个整数,表示最小的代价。
如果怎么连都连不出KK个棉花糖,请输出'No Answer'。
解析
题目特别坑,
连的边数 得到的树的个数
n-1 1
n-2 2
n-3 3
... ...
n-k k
所以我们如果想要连出k棵树,就需要连n-k条边。
也就是说最后是n-k条边而不是k-1条边;
明白这一点就是一个简单的kruscal
代码
#include<bits/stdc++.h> using namespace std; int n,m,k; int f[5005]; void clean() { for(int i=1;i<=n;i++) { f[i]=i; } }//初始化并查集 int mf(int v) { if(f[v]==v) return v; else { f[v]=mf(f[v]); return f[v]; } }//找爹 void mer(int a,int b) { int af=mf(a); int bf=mf(b); if(af!=bf) { f[bf]=af; } }//合并 struct make_edge { int a; int b; int w; };//每条边 make_edge edge[200005]; bool cmp(make_edge a,make_edge b) { return a.w<b.w; } int main() { cin>>n>>m>>k; clean(); for(int i=1;i<=m;i++) { int a,b,w; cin>>a>>b>>w; edge[i].a=a; edge[i].b=b; edge[i].w=w; } sort(edge+1,edge+m+1,cmp);//排序 int count=0;//边数 int sum=0; for(int i=1;i<=m;i++) { if(mf(edge[i].a)==mf(edge[i].b)) continue; else { mer(edge[i].a,edge[i].b); sum+=edge[i].w; count++; } if(count==n-k) { break; } } if(count<n-k) cout<<"No Answer"<<endl; else cout<<sum<<endl; return 0; }