洛谷P1195口袋的天空

题目背景

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

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

题目描述

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

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

输入输出格式

输入格式:

每组测试数据的

第一行有三个数N,M,K(1N1000,1M10000,1K10)

接下来M个数每行三个数X,Y,L表示X云和Y云可以通过L的代价连在一起。(1X,YN,0L<10000)

30%的数据N100,M1000

输出格式:

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

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

分析:
一眼扫过去,还以为是最小生成树的模板题,交了个模板上去全WA所以这是一道读题题

正解kruskal做法,题目叫求生成K朵棉花糖的最小代价.

由此我们可以发现提示在生成K颗树的最小代价求K颗树我们只需要(N-K)条边那我们记个数如果用kruskal做法就只需要依次加边直到加到(N-K)条边

代码:

#include <iostream>
#include <cstdio>
#include <algorithm>
using namespace std;
const int N=1e5+100;
const int M=N*2;
int root[N],n,m,k,ans,keay;
struct Edge
{
    int x,y,z;
}edges[M];
bool comp(struct Edge a,struct Edge b)
{
    return a.z<b.z;
}
int find(int x)//并查集(可能我和大家写的不一样)
{
    int y=x;
    while(y!=root[y])
    {
        y=root[y];
    }
    while(x!=root[x])
    {
        int ap=root[x];
        root[x]=y;
        x=ap;
    }
    return x;
}
int main()
{
    cin>>n>>m>>k;
    
    for(int i=1;i<=n;i++) root[i]=i;
    for(int i=1;i<=m;i++)
    cin>>edges[i].x>>edges[i].y>>edges[i].z;
    sort(edges+1,edges+1+m,comp);
    for(int i=1;i<=m;i++)
    {
        int fx=find(edges[i].x);
        int fy=find(edges[i].y);
        if(fx==fy) continue;
        else
        {
            root[fx]=fy;
            ans+=edges[i].z;
            keay++;
            if(keay==n-k)//这里坑点(N-K)条边构成K颗树
            {
                cout<<ans<<endl;
                return 0;
            }
            if(n-k<0)//如果都没有K朵云那么就不可能生成K颗树
            {
                cout<<"No Answer"<<endl;
                return 0;
            }
        }
    }
    return 0;
} 

 

猜你喜欢

转载自www.cnblogs.com/CCCPKeay/p/9887197.html