【洛谷 1195】口袋的天空

题目背景

小杉坐在教室里,透过口袋一样的窗户看口袋一样的天空。

有很多云飘在那里,看起来很漂亮,小杉想摘下那样美的几朵云,做成棉花糖。

题目描述

给你云朵的个数NN,再给你MM个关系,表示哪些云朵可以连在一起。

现在小杉要把所有云朵连成KK个棉花糖,一个棉花糖最少要用掉一朵云,小杉想知道他怎么连,花费的代价最小。

输入格式

每组测试数据的

第一行有三个数N,M,K(1 \le N \le 1000,1 \le M \le 10000,1 \le K \le 10)N,M,K(1N1000,1M10000,1K10)

接下来MM个数每行三个数X,Y,LX,Y,L,表示XX云和YY云可以通过LL的代价连在一起。(1 \le X,Y \le N,0 \le L<10000)(1X,YN,0L<10000)

30\%30%的数据N \le 100,M \le 1000N100,M1000

输出格式

对每组数据输出一行,仅有一个整数,表示最小的代价。

如果怎么连都连不出KK个棉花糖,请输出'No Answer'。

输入输出样例

输入 #1
3 1 2
1 2 1
输出 #1
1

说明/提示

厦门一中YMS原创

 

题解:本题要求连成k个生成树最小花费。kruskal的每次操作都会减少一颗生成树,故tot到达n-k停止即可  

 

#include<iostream>
#include<algorithm>
#include<queue>
#include<cmath>
#include<cstring>
#include<cstdlib>
#include<cstdio>
using namespace std;
typedef double db;
const int oo=0x3f3f3f3f;
const int N=200005;
int n,m,cp,tot,fa[N],b[N],c[N];
struct YCLL{
    int u,v;
    int va;
}e[N];
int ans=0;
bool cmp(YCLL aa,YCLL bb){
    return aa.va<bb.va;
}

int find(int x){
    if(x!=fa[x]) 
       fa[x]=find(fa[x]);
    return fa[x];
}
int op;
int main(){
    freopen("1195.in","r",stdin);
    freopen("1195.out","w",stdout);
    
    scanf("%d %d %d",&n,&m,&op); 
    for(int i=1;i<=n;i++) fa[i]=i;
    
    /*int ss=oo;
    for(int i=1;i<=n;i++){
        scanf("%d",&c[i]);
        ss=min(ss,c[i]);
    }*/
        
    int x,y,z;
    for(int i=1;i<=m;i++){
        scanf("%d %d %d",&x,&y,&z);
        e[i].u=x; e[i].v=y; e[i].va=z;
    }
    sort(e+1,e+m+1,cmp);
    for(int i=1;i<=m;i++){
        int uu=find(e[i].u);
        int vv=find(e[i].v);
        if(uu==vv) continue;
        ans+=e[i].va; 
        fa[uu]=vv; tot++;
        if(tot==(n-op)) break;
    }
    if(tot==(n-op)) printf("%d",ans);
    else printf("No Answer");
    return 0;
}

 

posted @ 2019-08-04 08:12  #Cookies#  阅读(159)  评论(0编辑  收藏  举报