[説明] NOIP2018_トラック構造(バイナリ/木DP /セット/貪欲

一部ポイント:M = 1つの直径、エッジ重みの菊図ソート、それぞれ最大及び最小合わせDPチェーンカバーハンを取ります

バイナリワード、答えの半分、それぞれの息子又はおよびアップロードするために一緒にX、またはおよび他の息子合わせ(MIDよりも大きい長さ)、、、XはF-息子をとる(統計点xがA LCAです)なぜなら

正の溶液およびバイナリ菊の図は、一緒になって、各点の息子は、連続的にちょうど中間上記右の2つの側面を撮影し、その後、実施左最大通過父親セットを取ります

より簡単には口で言う....

#include <ビット/ STDC ++ H>
 の#defineは長い長いllの
 使用 名前空間STDを、
const  int型 MAXN = 50009 ;
INTのN、M、ANS。
構造体ノード{
     int型V、NXT、W。
} E [MAXN << 1 ]。
int型のヘッド[MAXN]、CNT;
インラインボイド追加(int型 U、int型 V、INT W){
    E [ ++ CNT] .V = V; E [CNT] .W = W; E [CNT] .nxt =頭部[U];頭部[U] = CNT。
}
多重集合 < INT > S [MAXN]。
LL DFS(int型のx、int型 FA、int型K){
    S [X] .clear();
    int型のval;
    以下のためにint型 ; I I = I =ヘッド[X] {E [I] .nxt)
         INT Y = E [I] .V。もし(Y == FA)続けます
        ヴァル = DFS(Y、X、K)+ E [I] .W。
        もし ++(ヴァル> = k)はANS S [X] .insert(ヴァル)。
    }
    int型のmx = 0 ;
    一方、(!S [X] .empty()){
         もし、(S [X] .size()== 1戻り MAX(MX、* S [X] .begin())。
        多重集合 < INT > :: ITは、S [X] .lower_bound =イテレータ( - K-S * [X] .begin()); //は、合成電流及び> = LMT最小要素を見つける
        IF(ITを== S [X] .begin()&& S [X] .count(IT *)== 1)IT ++はIF(これは== S [X] .END()){ // 最大アップロードを取ることが見出されていない 
            MX = MAX(MX * S [X] .begin())。
            S [X] .erase(S [X] .find( * S [X] .begin()))。
        }
        他に { // 組み合わせは、要素の削除 
            ANSを++ ;
            S [X] .erase(S [X] .find( * IT))。
            S [X] .erase(S [X] .find( * S [X] .begin()))。
        }
    }
    リターンMX。
}
ブールチェック(LL用MD){ = 0 ;
    DFS(10 、MD)。
    もし(ANS> = M)リターン 1 リターン 0 ;
}
INT {main()の
    scanf関数(" %D%dの"、&​​N、&M); LLのR = 1 int型 I = 1、U、V、W、iがn <; iは++ ){
        scanf関数(" %D%D%D "、およびuは、&​​V、およびW)
        (U、V、W)を追加し、(W、UがV)を追加し、R + = W。
    }
    LLのL = 0、R / =(LL)M; R + = 1 ;
    一方、(L < R){
        中間LL = L + R >> 1 もし(チェック(MID))L =ミッド+ 1 他の R = ミッド;
    }
    printf(" %のLLD "、R- 1 )。
}

 

おすすめ

転載: www.cnblogs.com/superminivan/p/11769510.html
おすすめ