题目背景
小杉坐在教室里,透过口袋一样的窗户看口袋一样的天空。
有很多云飘在那里,看起来很漂亮,小杉想摘下那样美的几朵云,做成棉花糖。
题目描述
给你云朵的个数 N,再给你M 个关系,表示哪些云朵可以连在一起。
现在小杉要把所有云朵连成K 个棉花糖,一个棉花糖最少要用掉一朵云,小杉想知道他怎么连,花费的代价最小。
输入格式
第一行有三个数 N,M,K。
接下来 M 行每行三个数X,Y,L,表示 X 云和 Y 云可以通过 L 的代价连在一起。
输出格式
对每组数据输出一行,仅有一个整数,表示最小的代价。
如果怎么连都连不出 K 个棉花糖,请输出 No Answer
。
输入输出样例
输入 #1复制
3 1 2 1 2 1
输出 #1复制
1
说明/提示
对于 30% 的数据,1≤N≤100,1≤M≤103;
对于 100% 的数据,1≤N≤103,1≤M≤104,1≤K≤10,1≤X,Y≤N,0≤L<104。
题目分析
此题可以直接使用Keruskal,只要连n-k次边,就输出这几条边的边权值和,如果不行就输出No Answer
代码实现
#include<bits/stdc++.h>
using namespace std;
int n,m,k,x,y,l,p[250009],ans,cnt,sum=1;
struct Node{
int n1,n2,e;
friend bool operator <(Node a,Node b){
return a.e<b.e;
}
}edges[250009];
int find(int v) {
if(v!=p[v]) {
p[v]=find(p[v]);
}
return p[v];
}
vector<int>result;
void Keruskal(){
sort(edges+1,edges+m+1);
for(int i=1;i<=m;i++){
int t1=find(edges[i].n1);
int t2=find(edges[i].n2);
if(t1==t2)continue;
p[t2]=t1;
ans+=edges[i].e;
result.push_back(i);
cnt++;
if(cnt==n-k){
break;
}
}
}
int main(){
cin>>n>>m>>k;
for(int i=1;i<=n;i++){
p[i]=i;
}
for(int i=1;i<=m;i++){
cin>>x>>y>>l;
edges[i].e=l;
edges[i].n1=x;
edges[i].n2=y;
}
Keruskal();
if(cnt>=n-k){
cout<<ans;
}else{
cout<<"No Answer";
}
return 0;
}