トピックリンクします。https://vjudge.net/problem/POJ-3162
ツリーに、最大距離を求めて、ツリーの各ノードは、[I]と呼ばれ、その後満たす範囲maxの最大間隔[L、R]([I])を見つける - (分:質問は意図されています[I])<= M.
アイデアは:最初のステップは、最も長い距離の各ノードごとに算出した同じ問題ツリーDPは、私は別のブログ記事がhttps://www.cnblogs.com/FrankChen831X/p/11375572書かれていることをhdoj2196します。 HTML。最大距離[I]を得た後、最小及び最大セグメントツリーのメンテナンス間隔を確立します。次いで、i、jは再び横断二つのポインタは、それぞれの時間は、[I、J]の答えを更新最大および最小ANS1のANS2の得られるためではないすべてのjの初期化、O(nlogn)の合計複雑。
ACコード:
書式#include <cstdioを> する#include <アルゴリズム> 使用して 名前空間はstdを、 typedefの長い 長いLL。 const int型 MAXN = 1E6 + 5 。 constの LL INF = 0x3f3f3f3f3f3f3f3f 。 int型N、ANS、CNT、ヘッド[MAXN]、PT [MAXN]、[MAXN]。 LL M、DP [MAXN] [ 3 ]、ANS1、ANS2。 構造体ノード1 { int型V、NEX。 LLのワット。 }エッジ[MAXN << 1 ]。 構造体NODE2 { int型のL、R。 LL MAX、MIN。 } TR [MAXN << 2 ]。 ボイド ADDE(INT U、INT V、LLのW){ エッジ[ ++ CNT] .V = V。 エッジ[CNT] .W = W。 エッジ[CNT] .nex = 頭部[U]。 ヘッド[U] = CNT。 } ボイド DFS1(INT U、INT FA){ ため(int型 ; I I = I =ヘッド[U] {エッジ[I] .nex) のint V = エッジ[I] .V。 W LL = エッジ[I] .W。 もし(== FA V)続けます。 DFS1(V、U); もし(W + DP [V] [ 0]> DP [U] [ 0 ]){ DP [U] [ 1 ] DPを= [U] [ 0 ]。 DP [U] [ 0 ] = W + DP [V] [ 0 ]。 PT [U] = V。 } そう であれば(W + DP [V] [ 0 ]> DP [U] [ 1 ]) DP [U] [ 1 ] = W + DP [V] [ 0 ]。 } } ボイド DFS2(INT U、INT FA){ ため(int型 I =ヘッド[U]; iが、i = エッジ[I] .nex){ int型 V = エッジ[I] .V。 LL W = エッジ[I] .W。 もし(== FA V)続けます。 もし(!V = PT [U]) DP [V] [ 2 ] +最大W =(DP [U] [ 0 ]、DP [U] [ 2 ])。 他 DP [V] [ 2 ] +最大W =(DP [U] [ 1 ]、DP [U] [ 2 ])。 DFS2(V、U); } } ボイド押し上げ(int型V){ TR [V] .MAX = MAX(TR [V << 1 ] .MAX、TR [V << 1 | 1 ] .MAX)。 TR [V] .Min =分(TR [V << 1 ] .Min、TR [V <<1 | 1 ] .Min)。 } ボイドビルド(int型 V、INTを L、INT R){ TR [V] .L = L、T R [V] .R = R。 もし(L == R){ TR [V] .MAX = TR [V] .Minは= [L]を、 返します。 } INT半ば=(L + R)>> 1 。 構築(V << 1 、L、ミッド)。 構築(V << 1 | 1、ミッド+ 1 、R); 腕立て伏せ(V); } 空のクエリ(int型 V、int型の L、int型R){ 場合(L <= T R [V] .L && R> = T R [V] .R){ ANS1 = MAX(ANS1、TR [V] .MAX)。 ANS2 = 分(ANS2、TR [V] .Min)。 返します。 } INT半ば=(TR [V] .L + T R [V] .R)>> 1 。 もし(L <= MID)クエリ(V << 1 、L、R)。 もし(R>中旬)クエリ(V << 1 | 1 、L、R); } int型のmain(){ scanf関数(" %d個の%のLLD "、&N、&M)。 以下のための(int型 I =2 ; iは= N <; ++ I){ int型V、LLのW。 scanf関数(" %Dの%のLLD "、&V、およびW) ADDE(I、V、W)。 ADDE(V、I、W)。 } DFS1(1、0 ); DFS2(1、0 ); 以下のために(int型 i = 1 ; iは= N <; ++ I) [I] = MAX(DP [I] [ 0 ]、DP [I] [ 2 ])。 ビルド(1、1 、N) int型 J = 1 ; にとって(int型 I = 1 ; ++; iが<= N I){ 一方(j <= N){ ANS1 = 0、ANS2 = INF。 クエリ(1 、i、j)は、 もし(ANS1-ANS2> M)ブレーク。 ++ J; } ANS = MAX(ANS、J- I)。 } のprintf(" %d個の\ n " 、ANS)。 リターン 0 ; }