P1195 口袋的天空
题目背景
小杉坐在教室里,透过口袋一样的窗户看口袋一样的天空。
有很多云飘在那里,看起来很漂亮,小杉想摘下那样美的几朵云,做成棉花糖。
题目描述
给你云朵的个数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'。
输入 #1
3 1 2
1 2 1
输出 #1
1 .
思路:
我们只需要想一下要做出k个棉花糖
就是生成k棵树
总共n个点
生成1棵树连边n - 1条
生成2棵树连边n - 2条
................................
生成k棵树连边n - k条
代码:
#include<iostream>
#include<bits/stdc++.h>
using namespace std;
const int max_size=1000;
int pre[max_size],height[max_size];
int find_set(int x){
return x==pre[x]?x:find_set(pre[x]);
}
void init_set(int count){
for (int i = 1; i <= count; i++)
{
pre[i]=i;
height[i]=0;
}
}
void union_set(int x,int y )
{
x = find_set(x);
y = find_set(y);
if (height[x]==height[y])
{
pre[y]=x;
}else
{
if (height[x]<height[y])
pre[x]=y;
else
pre[y]=x;
}
}
//结构体
struct node{
int start,end,weight;
}arr[max_size];
bool cmp(const node &a ,const node &b){
return a.weight<b.weight;
}
int main(){
int n,m,k;
cin>>n>>m>>k;
init_set(n);
for (int i = 1; i <= m; i++)
{
cin>>arr[i].start>>arr[i].end>>arr[i].weight;
}
sort(arr+1,arr+1+m,cmp);
int cnt=0,sum=0;
for (int i = 1; i <= m; i++)
{
int x = find_set(arr[i].start);
int y = find_set(arr[i].end);
if (x!=y)
{
pre[x]=y;
cnt++;
sum+=arr[i].weight;
}
if (cnt>=n-k)
{
break;
}
}
if(cnt>=n-k) //如果选了n-k条边,可以搞最小生成树
cout<<sum<<endl; //输出最小权值
else
cout<<"No Answer"<<endl; //要不然选了m条边还都搞不好,不能构成最小生成树
return 0; //终于完事了
}