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

洛谷P1195口袋的天空

題目背景

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

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

題目描述

給你雲朵的個數N,再給你M個關係,表示哪些雲朵可以連在一起。

現在小杉要把所有云朵連成K個棉花糖,一個棉花糖最少要用掉一朵雲,小杉想知道他怎麼連,花費的代價最小。

輸入輸出格式

輸入格式:

每組測試資料的

第一行有三個數N,M,K(1N1000,1M10000,1K10)

接下來M個數每行三個數X,Y,L表示X雲和Y雲可以通過L的代價連在一起。(1X,YN,0L<10000)

30%的資料N100,M1000

輸出格式:

對每組資料輸出一行,僅有一個整數,表示最小的代價。

如果怎麼連都連不出K個棉花糖,請輸出'No Answer'。

分析:
一眼掃過去,還以為是最小生成樹的模板題,交了個模板上去全WA所以這是一道讀題題

正解kruskal做法,題目叫求生成K朵棉花糖的最小代價.

由此我們可以發現提示在生成K顆樹的最小代價求K顆樹我們只需要(N-K)條邊那我們記個數如果用kruskal做法就只需要依次加邊直到加到(N-K)條邊

程式碼:

#include <iostream>
#include <cstdio>
#include <algorithm>
using namespace std;
const int
N=1e5+100; const int M=N*2; int root[N],n,m,k,ans,keay; struct Edge { int x,y,z; }edges[M]; bool comp(struct Edge a,struct Edge b) { return a.z<b.z; } int find(int x)//並查集(可能我和大家寫的不一樣) { int y=x; while(y!=root[y]) { y=root[y]; } while(x!=root[x]) { int
ap=root[x]; root[x]=y; x=ap; } return x; } int main() { cin>>n>>m>>k; for(int i=1;i<=n;i++) root[i]=i; for(int i=1;i<=m;i++) cin>>edges[i].x>>edges[i].y>>edges[i].z; sort(edges+1,edges+1+m,comp); for(int i=1;i<=m;i++) { int fx=find(edges[i].x); int fy=find(edges[i].y); if(fx==fy) continue; else { root[fx]=fy; ans+=edges[i].z; keay++; if(keay==n-k)//這裡坑點(N-K)條邊構成K顆樹 { cout<<ans<<endl; return 0; } if(n-k<0)//如果都沒有K朵雲那麼就不可能生成K顆樹 { cout<<"No Answer"<<endl; return 0; } } } return 0; }