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'。
策略
并查集与最小生成树的数量关系
已经连过的边+题目要求的k(即建立的集合个数)=n个点时 题目有解
#include<bits/stdc++.h>
using namespace std;
int father[1005];
int n,m,k;
int sum;
int b[1005];
int find(int x){
if(father[x]!=x)
father[x]=find(father[x]);
return father[x];
}
void unionn(int r1,int r2){
father[r1]=r2;
}
struct data{
int x,y,dis;
}edge[10005];
bool cmp(data a,data b){
return a.dis<b.dis;
}
int main(){
scanf("%d%d%d",&n,&m,&k);
for(int i=1;i<=n;i++)
father[i]=i;
for(int i=1;i<=m;i++)
scanf("%d%d%d",&edge[i].x,&edge[i].y,&edge[i].dis),b[edge[i].x]++,b[edge[i].y]++;
int cnt=0;
sort(edge+1,edge+1+m,cmp);
for(int i=1;i<=m;i++){
int x=edge[i].x;
int y=edge[i].y;
int r1=find(x);
int r2=find(y);
if(r1!=r2){
unionn(r1,r2);
sum+=edge[i].dis;
cnt++;
if(cnt+k==n){
printf("%d",sum);
return 0;
}
}
}
}