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'。

 

输入输出样例

输入样例#1: 复制
3 1 2
1 2 1
输出样例#1: 复制
1

说明

厦门一中YMS原创

 

最小生成树的变式

我们先建立一个朴素最小生成树,为了得到k个最下生成树,我们相当于就是减掉k-1条边就行了,那么这k-1条边一定是越大越好

但是我们已经sort一次啦呀,这已经完全ok啦啊

那就早点跳出去嘛,cnt=n-k的时候跳出去就可以了

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
#define inf 2147483647
const ll INF = 0x3f3f3f3f3f3f3f3fll;
#define ri register int
template <class T> inline T min(T a, T b, T c)
{
    return min(min(a, b), c);
}
template <class T> inline T max(T a, T b, T c)
{
    return max(max(a, b), c);
}
template <class T> inline T min(T a, T b, T c, T d)
{
    return min(min(a, b), min(c, d));
}
template <class T> inline T max(T a, T b, T c, T d)
{
    return max(max(a, b), max(c, d));
}
#define scanf1(x) scanf("%d", &x)
#define scanf2(x, y) scanf("%d%d", &x, &y)
#define scanf3(x, y, z) scanf("%d%d%d", &x, &y, &z)
#define scanf4(x, y, z, X) scanf("%d%d%d%d", &x, &y, &z, &X)
#define pi acos(-1)
#define me(x, y) memset(x, y, sizeof(x));
#define For(i, a, b) for (int i = a; i <= b; i++)
#define FFor(i, a, b) for (int i = a; i >= b; i--)
#define bug printf("***********\n");
#define mp make_pair
#define pb push_back
const int N = 100005;
// name*******************************
struct edge
{
    int to,from,w;
} e[N];
int pre[N];
int Rank[N];
int cnt=0;
int ans=0;
int n,m,k;
// function******************************
bool cmp(edge x,edge y)
{
    return x.w<y.w;
}
void init(int x)
{
    pre[x]=-1;
    Rank[x]=0;
}
int find(int x)
{
    int r=x;
    while(pre[r]!=-1)r=pre[r];
    while(x!=r)
    {
        int t=pre[x];
        pre[x]=r;
        x=t;
    }
    return r;
}
void unionone(int a,int b)
{
    int t1=find(a);
    int t2=find(b);
    if(Rank[t1]>Rank[t2])
        pre[t2]=t1;
    else
        pre[t1]=t2;
    if(Rank[t1]==Rank[t2])
        Rank[t2]++;
}
//***************************************
int main()
{
//    ios::sync_with_stdio(0);
//    cin.tie(0);
    // freopen("test.txt", "r", stdin);
    //  freopen("outout.txt","w",stdout);
    cin>>n>>m>>k;
    For(i,1,n)
    init(i);
    For(i,1,m)
    cin>>e[i].to>>e[i].from>>e[i].w;
    sort(e+1,e+1+m,cmp);
    For(i,1,m)
    {
        if(find(e[i].to)!=find(e[i].from))
        {
            unionone(e[i].to,e[i].from);
            cnt++;
            ans+=e[i].w;
            if(cnt==n-k){
                cout<<ans;
                return 0;
            }
        }
    }
    cout<<"No Answer";

    return 0;
}

 

posted @ 2018-04-02 23:21  planche  阅读(128)  评论(0编辑  收藏  举报