羅区P4178ツリー

パーティションと見なさポイントは、サブツリーのために、ルートは各点までの距離と、ソート、デュアルスキャンポインタを取得しますが、このパスは息子カウントアップし、各息子のために再びそれを行う、保存から同じになりますにアクセスしてください。

 

書式#include <cstdioを> 
する#include <CStringの> 
の#include <アルゴリズム> 
書式#include <キュー>
 使用して 名前空間はstdを、
typedefの長い 長いLL。
const  int型の N = 40005 ;
チャーはrB [ 1 << 21 ]、* S * T。
インラインチャー GC(){ 戻り S == T &&(T =(S = rBの)+関数fread(RB、11 << 21、STDIN)、S == T)EOF:* S ++ ;} 
インラインint型RD( ){
     チャー C = GC()。
    一方、(C < 48 || C> 57)C = GC()。
    INT X = C&15 (C = GC(); C> = 48個の && C <= 57、C = GC())x =(x << 3)+(X << 1)+(C&15 )。
    リターンのx; 
} 
INT [N <<にG [N]、1 ]、W [N << 1 ]、NXT [N << 1 ]、CNT = 0 、SZ [N]、[N] F、和、RT、d [N]、T [N]、TOT、K。
LL ANS = 0LL。
BOOL VIS [N]、INQ [N]。
キュー < 整数 > Q;ボイド(ADD INT U、INT V、INT c){ 
    [に対する CNT ++] = V [CNT、W Cが=; NXT [CNT] = G [U]、G [U] = CNT。
    【に [CNT、W Cが=; NXT [CNT] = G [V]、G [V] = CNT ++] = U CNT。
} 
ボイド getrt(int型 Uを、INT FA){   // 点分治搜重心
    INT I、V。
    SZ [U] = 1 ; F [U] = 0 ;
    以下のための(I = G [U]; I; I = NXT [I])であれば(VIS [V =乃至[I]] && V =!FA){ 
        getrt(V、U)。
        SZ [U] + = SZ [V]。
        F [U] =MAX(F [U]、SZ [V])。
    } 
    F [U] = MAX(F [U]、sum- SZ [U])。
    もし RT =([U] <F [RT] F)U。
} 
インラインLL計算値(INTは U、int型K){
     int型I、H、V、L、R。
    LL ANS = 0LL。
    memset(INQ、0はsizeof (INQ))。
    [U] INQ = 1 ; T [TOT = 1 ] = D [U] = 0 ; Q.push(U)。
    一方、(!{Q.empty())
        H = Q.front(); Q.pop()。
        以下のための(I = G [H]; I; I = NXT [i])とする場合(!VIS [Vへ= [I]] &&!INQ [V] &&(D [V] D = [H] + W [I])<= K){   // 、kは回答を寄与していない距離よりも大きいです保存せずに 
            T [TOT ++] = ; D [V] 
            INQ [V] = 1 ; 
            Q.push(V); 
        } 
    } 
    ソート(Tの + 1、TOT + T + 1 のための(L = 1、Rを&LT = TOT; L <= R&LT; ++ L){
         一方(L <= R&LT && T [L] T + [R&LT]> K) - R&LT;
         IF(L> R&LT)BREAK ; 
        ANS + R- = L; 
    } 
    リターンANS; 
} 
ボイド(解決INT {U)を
    int型のI、V。
    VIS [U] = 1 ; ANS + = CALC(U、K)。
    以下のための(I = G [U]; I; I = NXT [I])であれば(!VIS [V = 乃至[I]]){ 
        ANS - = CALC(V、K-(W [i]は<< 1 ) );  = SZ [V]; RT = 0 ; getrt(V、U)を、
        (RT)を解きます。
    } 
} 
int型のmain(){
     int型、N = F [ 0 ] =合計= RD()、I、U、V、C。
    (i = 1 ; iがn <; ++ I){ 
        U = RD(); V = RD(); C = RD()。
        (C、U、V)を追加します。
    } 
    K =RD(); 
    getrt(10 );(RT)を解きます。
    printf(" %のLLD " 、ANS)。
    リターン 0 ; 
}
コードの表示

 

おすすめ

転載: www.cnblogs.com/sunshine-chen/p/11258752.html