luoguP1195 口袋的天空 x
阿新 • • 發佈:2017-07-18
現在 生成 bool 通過 窗戶 col 輸出格式 sky cin
P1195 口袋的天空
-
- 378通過
- 867提交
- 題目提供者該用戶不存在
- 標簽 雲端
- 難度 普及+/提高
- 時空限制 1s / 128MB
題目背景
小杉坐在教室裏,透過口袋一樣的窗戶看口袋一樣的天空。
有很多雲飄在那裏,看起來很漂亮,小杉想摘下那樣美的幾朵雲,做成棉花糖。
題目描述
給你雲朵的個數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
說明
廈門一中YMS原創
思路:
首先要想明白題目讓你做什麽:
更改成通俗的話就是將n個點再添加上幾條邊之後變為k個點,並且使得連邊的花費達到最小
那麽就很明白啦~如下圖:
想要將8個點,變為3個點,所以需要搞一個最小生成樹,將與其他邊相連時邊權較小的6個點連起來,如下圖:
然後 通過大量的實驗可以的證:
只需要搞一個點數為n-k的最小生成樹即可成功
上代碼:
#include <algorithm> #include <iostream> using namespace std; const int INF = 0x7fffffff; const int N = 1010; const int M = 10010; int n,m,k,ans,cnt; intdad[N]; struct Sky { int u,v,w; bool operator < (const Sky &qwq)const { return w < qwq.w; } }s[M]; int getdad(int x) {return dad[x] == x ? x : dad[x] = getdad(dad[x]);} void kruskal() { for(int i=1;i<=n;i++) dad[i]=i; sort(s+1,s+1+m); for(int i=1;i<=m;i++) { int f1=getdad(s[i].u),f2=getdad(s[i].v); if(f1!=f2) { dad[f1]=f2; ans+=s[i].w; cnt++; } if(cnt==k)//此時的k為輸入的n-k break; } if(cnt<k) { cout<<"No Answer";//其實這個去掉也可以,因為沒有數據搞這裏... return; } cout<<ans; } void add(int b,int u,int v,int w) {s[b].u=u,s[b].v=v,s[b].w=w;} int main() { cin>>n>>m>>k; k=n-k;//直接先把k變為n-k for(int i=1,x,y,l;i<=m;i++) { cin>>x>>y>>l; add(i,x,y,l); } kruskal(); return 0; }
luoguP1195 口袋的天空 x