洛谷P1195口袋的天空
阿新 • • 發佈:2018-11-01
題目背景
小杉坐在教室裡,透過口袋一樣的窗戶看口袋一樣的天空。
有很多雲飄在那裡,看起來很漂亮,小杉想摘下那樣美的幾朵雲,做成棉花糖。
題目描述
給你雲朵的個數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'。
分析:
一眼掃過去,還以為是最小生成樹的模板題,交了個模板上去全WA所以這是一道讀題題
正解kruskal做法,題目叫求生成K朵棉花糖的最小代價.
由此我們可以發現提示在生成K顆樹的最小代價求K顆樹我們只需要(N-K)條邊那我們記個數如果用kruskal做法就只需要依次加邊直到加到(N-K)條邊
程式碼:
#include <iostream> #include <cstdio> #include <algorithm> using namespace std; const intN=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]) { intap=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; }