パーティションと見なさポイントは、サブツリーのために、ルートは各点までの距離と、ソート、デュアルスキャンポインタを取得しますが、このパスは息子カウントアップし、各息子のために再びそれを行う、保存から同じになりますにアクセスしてください。
書式#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、1、1 << 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(1、0 );(RT)を解きます。 printf(" %のLLD " 、ANS)。 リターン 0 ; }