Vijos:P1234口袋的天空
Posted vCoders
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Vijos:P1234口袋的天空相关的知识,希望对你有一定的参考价值。
背景
小杉坐在教室里,透过口袋一样的窗户看口袋一样的天空。
有很多云飘在那里,看起来很漂亮,小杉想摘下那样美的几朵云,做成棉花糖。
描述
给你云朵的个数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‘。
输入:
3 1 2
1 2 1
输出
1
思路:N朵云最多做N个棉花糖,多连一条边就少做一个棉花糖。
#include<cstdio> #include<cstring> #include<algorithm> using namespace std; const int MAXN=10005; struct Edge{ int u,v,w; }es[MAXN]; int n,m,k; int par[MAXN],rnk[MAXN]; bool comp(const Edge &e1,const Edge &e2) { return e1.w < e2.w; } void prep() { for(int i=0;i<MAXN;i++) { par[i]=i; rnk[i]=0; } } int fnd(int x) { if(par[x]==x) return x; return par[x]=fnd(par[x]); } void unite(int u,int v) { int a=fnd(u); int b=fnd(v); if(a==b) return ; if(rnk[a]<rnk[b]) { par[a]=b; } else { par[b]=a; if(rnk[a]==rnk[b]) rnk[a]++; } } bool same(int u,int v) { return fnd(u)==fnd(v); } int main() { scanf("%d%d%d",&n,&m,&k); for(int i=0;i<m;i++) { scanf("%d%d%d",&es[i].u,&es[i].v,&es[i].w); } if(k==n) { printf("0\n"); return 0; } if(k>n) { printf("No Answer\n"); return 0; } sort(es,es+m,comp); prep(); int cnt=0; int res=0; for(int i=0;i<m;i++) { if(!same(es[i].u,es[i].v)) { unite(es[i].u,es[i].v); res+=es[i].w; cnt++; if(n-cnt==k) { break; } } } if(n-cnt==k) printf("%d\n",res); else printf("No Answer\n"); return 0; }
以上是关于Vijos:P1234口袋的天空的主要内容,如果未能解决你的问题,请参考以下文章