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'。
输入输出样例
说明
厦门一中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; }