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;
            }
        }
    }
}