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

洛谷P1195 口袋的天空 題解

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