1. 程式人生 > >口袋的天空

口袋的天空

最小 content node display 數據 pla mes 接下來 stream

題目描述

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

這一道題目大意就是說,原來要的是一顆生成樹,現在要K棵。我們可以大膽猜想一下,如果一顆生成樹連通至少需要N-1條邊,那麽兩棵生成樹的生成只需要N-2邊,原因就是我們可以把原來一棵生成樹中的任意一條邊刪去,這樣就又有了一棵生成樹。所以,要生成K個生成樹,我們只需要連通N-K條邊,就可以了。

技術分享
 1 #include <cmath>
 2 #include <cstdio>
 3 #include <cstring>
 4 #include <iostream>
 5 #include <algorithm>
 6
7 using namespace std; 8 9 struct node 10 { 11 int u,v,cost; 12 }; 13 14 node a[100005]; 15 int f[100005]; 16 int N; 17 int Len=0; 18 19 bool cmp(node i,node j) 20 { 21 return i.cost < j.cost; 22 } 23 24 int find(int X) 25 { 26 if (f[X] != X) f[X]=find(f[X]); 27 return f[X]; 28 }
29 30 int main() 31 { 32 int M,K; 33 scanf("%d%d%d",&N,&M,&K); 34 for (int i=1; i<=N; i++) 35 { 36 f[i]=i; 37 } 38 for (int i=1; i<=M; i++) 39 { 40 scanf("%d%d%d",&a[i].u,&a[i].v,&a[i].cost); 41 } 42 int ans=0; int total=0; 43 sort(a+1,a+M+1,cmp); 44 for (int i=1; i<=M; i++) 45 { 46 int fx=find(a[i].u); 47 int fy=find(a[i].v); 48 if (fx > fy) swap(fx,fy); 49 if (fx == fy) continue; 50 if (fx != fy) 51 { 52 f[fy]=fx; 53 ans+=a[i].cost; 54 total++; 55 if (total == N - K) break; 56 } 57 } 58 if (total < N - K) printf("No Answer\n"); 59 else printf("%d\n",ans); 60 }
Show My Ugly Code

口袋的天空