0
点赞
收藏
分享

微信扫一扫

洛谷P1195 口袋里的天空

云竹文斋 2022-05-01 阅读 19
c++蓝桥杯

题目背景

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

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

题目描述

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

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

输入格式

第一行有三个数 N,M,K。

接下来 MM 行每行三个数 X,Y表示X云和 Y 云可以通过L 的代价连在一起。

输出格式

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

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

输入输出样例

输入

3 1 2
1 2 1

输出

1

思路

 由于需要有k个棉花糖,则可理解为将云朵分成k个部分。
特判棉花糖大于云朵的数量,此时无解。
那么对于一个生成树来说,点为n个,边则有n-1条。如果要想分割成k个部分,需要减去(k-1)条边
即所需要的边为:(n-1)-(k-1) = n-k
也就是对原图进行Kruskal且只连接 n-k 条较小边即可

代码

#include<iostream>
#include<algorithm>
using namespace std;
const int MAXN = 1e3+5;
const int MAXM = 1e4+5;
struct node
{
    int x,y,z;
    friend bool operator < (node a,node b) 
    {
        return a.z < b.z;
   	}
}
a[MAXM];
int dis[MAXN];
int getf(int p) 
{
    return dis[p]==p?p:dis[p]=getf(dis[p]);
}
int main() 
{
    int n,m,k;
    cin>>n>>m>>k;
    for(int i = 1;i <= n;i++)
    {
        dis[i] = i;
    }
    for(int i = 1;i <= m;i++)
    {
        int x,y,z;
        cin>>x>>y>>z;
        a[i] = {x,y,z};
    }
    if(k>n)
    {
        cout<<"No Answer\n";
        return 0;
    }
    sort(a+1,a+1+m);
    int ans = 0,num = 0;
    for(int i = 1;i <= m;i++) 
    {
        node tmp = a[i];
        if(getf(tmp.x)!=getf(tmp.y)) 
        {
            ans += tmp.z;
            dis[getf(tmp.x)] = dis[getf(tmp.y)];
            num++;/
        }
        if(num==n-k) 
        {
            break;
        }
    }
    if(num!=n-k)
    {
        cout<<"No Answer\n";
    }
    else 
    {
        cout<<ans;
    }
    return 0;
}

感谢您选择屹立科技,更多资源请见官网:屹立科教 | 上线了sxl.cn

举报

相关推荐

0 条评论