zoukankan      html  css  js  c++  java
  • 【洛谷】【最小生成树】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个棉花糖”花费的代价最小.

    由于一朵云就可以是一个棉花糖,所以那些连边代价大的云朵就不要连,

    也就是说有((k-1))朵云不要去管他们,剩下的((n-k+1))朵云连成一个棉花糖,总共使用了(n)朵云连成了(k)个棉花糖.

    使用Kruskal做MST,连((n-k))条边就好.



    [Code:]

    #include<iostream>
    #include<cstdio>
    #include<algorithm>
    using namespace std;
    
    const int MAXN = 1000 + 1;
    const int MAXM = 10000 + 1;
    
    int n, m, k;
    int fa[MAXN];
    
    struct Edge {
    	int x, y, l;
    }h[MAXM];
    
    inline bool cmp(Edge a, Edge b) {
    	return a.l < b.l;
    }
    
    int find(int x) {
    	if(fa[x] != x) fa[x] = find(fa[x]);
    	return fa[x];
    }
    
    int main() {
    	scanf("%d%d%d", &n, &m, &k);
    	for(int i=1; i<=n; ++i) fa[i] = i;
    	for(int i=1; i<=m; ++i)
    		scanf("%d%d%d", &h[i].x, &h[i].y, &h[i].l);
    	sort(h + 1, h + m + 1, cmp);
    	int tot = 0, num = 0;
    	for(int i=1; i<=m; ++i) {
    		int fx = find(h[i].x), fy = find(h[i].y);
    		if(fx != fy) {
    			fa[fx] = fy;
    			tot += h[i].l;
    			++num;
    		}
    		if(num == n-k) break;
    	}
    	if(num < n-k) puts("No Answer");
    	else printf("%d
    ", tot);
    }
    
  • 相关阅读:
    【题解】 bzoj1191: [HNOI2006]超级英雄Hero (二分图)
    谈谈Android项目框架的前世今生
    十四个好用的开源漏洞检测工具
    关于Java导出100万行数据到Excel的优化方案
    逗号分割符--字段中含逗号等情况的解析方法Java实现
    Java日期处理
    服务器&浏览器伪装的故事
    浏览器User-agent简史(user-agent)
    修改tomcat服务器banner的方法
    life_motto
  • 原文地址:https://www.cnblogs.com/devilk-sjj/p/9088346.html
Copyright © 2011-2022 走看看