洛谷P1195 口袋的天空 題解
阿新 • • 發佈:2018-11-04
2018年04月27日
題目背景
小杉坐在教室裡,透過口袋一樣的窗戶看口袋一樣的天空。
有很多雲飄在那裡,看起來很漂亮,小杉想摘下那樣美的幾朵雲,做成棉花糖。
題目描述
給你雲朵的個數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:
3 1 2
1 2 1
輸出樣例#1:
1
果然是並查集orz
//參考了一下題解紅名dalao的思路
//也學習了一下operator的用法w
先放程式碼~(蒟蒻的程式碼可以說是很易懂了)
#include<bits/stdc++.h>//1195 using namespace std; int N,M,K,ans,now,o,p; int fat[100010];//祖宗 struct node{ int q;//起點 int w;//重點 int e;//代價 }qwq[100010]; bool operator<(node a,node b){ return a.e<b.e; } int findf(int x){ return fat[x]==x?fat[x]:fat[x]=findf(fat[x]); }//路徑壓縮 int main() { cin>>N>>M>>K; for(int i=1;i<=N;i++){ fat[i]=i; } for(int i=1;i<=M;i++){ cin>>qwq[i].q>>qwq[i].w>>qwq[i].e; } sort(qwq+1,qwq+M+1);//價值排序,從最小的開始連 for(int i=1;i<=M;i++){ o=findf(qwq[i].q); p=findf(qwq[i].w);//分別找父親 if(o!=p){//連過就跳過了 fat[o]=p;//合併 now++;//記錄邊的數量 ans+=qwq[i].e;}//通通連起來! //一棵有n個節點的樹有n-1條邊 if(now==N-K){//k棵樹,n個節點,就有n-k條邊 cout<<ans<<endl; return 0; } } cout<<"No Answer"<<endl; return 0; }
開心地結束了~
用了半個多小時……第一遍提交還re了
教訓是:一維陣列不要怕開大233333333
哦對了,還有一點
重置運算子的函式寫在裡面struct的話必須加const
bool operator <(node a) const;
在外面就像我這樣寫就ok