1. 程式人生 > >【最小生成樹】口袋的天空

【最小生成樹】口袋的天空

%d 試題 output str dig syntax 棉花糖 esp tput

口袋的天空

背景

小杉坐在教室裏,透過口袋一樣的窗戶看口袋一樣的天空。

有很多雲飄在那裏,看起來很漂亮,小杉想摘下那樣美的幾朵雲,做成棉花糖。

描述

給你雲朵的個數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

樣例輸入1

3 1 2
1 2 1
Copy

樣例輸出1

1
Copy

限制

每個測試點1s

提示

樣例2:
Input:
3 1 1
1 2 1

Output:
No Answer

來源

lolanv

試題分析

最小生成樹模板題,直接將最後一個棉花糖連成最小生成樹,剩下K-1個用單個的雲朵來當棉花糖就好了

代碼

#include<iostream>
#include<cstring>
#include<cstdio>
#include<algorithm>
using namespace std;
inline int read(){
	int x=0,f=1;char c=getchar();
	for(;!isdigit(c);c=getchar()) if(c==‘-‘) f=-1;
	for(;isdigit(c);c=getchar()) x=x*10+c-‘0‘;
	return x*f;
}
const int INF = 9999999;
struct data{
	int x,y,v;
}e[1000001];
bool cmp(data a,data b){
	return a.v<b.v;
}
int fa[100001];
int find(int x){
	if(x!=fa[x]) return fa[x]=find(fa[x]);
	return x;
}
int N,M,K; int ans;
int main(){
	N=read(),M=read(),K=read();
	for(int i=1;i<=M;i++){
	    e[i].x=read(),e[i].y=read();
	    e[i].v=read();
	}
	sort(e+1,e+M+1,cmp); int cnt=N;
	for(int i=1;i<=N;i++) fa[i]=i;
	for(int i=1;i<=M&&cnt>K;i++){
		int u=find(e[i].x),v=find(e[i].y);
		if(u!=v){
			ans+=e[i].v;
			cnt--;fa[v]=u;
		}
	}
	printf("%d\n",ans);
	return 0;
}

  

【最小生成樹】口袋的天空