トピック:
質問の意味:木を考えると、各ノードは、それぞれxとtの2、についての情報を持っており、このノード上のクッキー、上の手の数は、時間のノード上のビスケットを食べます。その後、我々は、上の手を持って、両方の個人を反転させます。
◉上側の手はそうすることができ:Tがノードに到着した合計時間を指定して、ルート・ノード1に返す必要があり、あなたには、いくつかのノードの間にいくつかのクッキーを食べることを選択することができますでは(前提は、残りの時間は、ルート・ノードに戻りますことを確認することです) ;
◉フリップはそうすることができます:ちょうど側縁が破壊されたことをより多くのように食べるように、上側の手を取得し、あなたは、このプロセスをスキップすることができる場所を選択しても、子供たちの間で、この位置に到達しました。
Q:与えられた総時間Tは、ただ食べるためにクッキーの最大数を取得します。
分析:各ノードが3つの選択肢を持って、我々はDP1、DP2、DP3を書きます。
DP1:ビスケットを食べて、現在の位置から上がります。
DP2:子どもに沿って現在の位置からアップビスケットの数を食べに行く。(このステップは、現在の場所での作業のルート、あなたが直接、最大を選択することができますので、それは、上側の手であるため)
DP3:クッキーの2倍以上の数を食べに子供たちに沿って行くには、現在の位置から、(ビスケットの最大数を食べているので、我々は最大の秒を選んだので、FLACは、上側の手を防ぐことができます)
DFSは、DP2を行うとき、あなたはDP3を計算することができ、バック、この木を扱います。
その後、我々はその後、答えは2を分離することができ、X * T X対応ビスケットを食べるように完全な変換時間がかかるため、最大かつ最も大きい第2のT xとノード情報、クッキーの数を持っています。
#include <ビット/ STDC ++ H> 使用して 名前空間STDを、 #define PB一back の#define LSONルート<< 1、L、midd の#define rsonルート<< 1 | 1、midd + 1、R typedefの長い ロングLL。 const int型 M = 1E6 + 5 。 LL X [M]、T [M]。 構造体ノード{ int型、U。 wはちゃいます。 }。 ベクター <ノード> G [M]。 構造体ノード{ LL TI、NUM。 }ツリー[M << 2 ]。 int型のn; ボイド更新(LL NUM、LL TI、LL根、LL、L、LL R){ もし(L == R){ ツリー[ルート] .ti + = NUM * TI。 ツリー[ルート] .num + = NUM。 リターン; } INT midd =(L + R)>> 1 。 もし(TI <= midd) 更新(NUM、TI、LSON)。 他の 更新(NUM、TI、rson)。 ツリー[ルート] .ti =ツリー[ルート<< 1 ] .ti +ツリー[ルート<< 1 | 1 ] .ti。 ツリー[ルート] .num =ツリー[ルート<< 1 ] .num +ツリー[ルート<< 1 | 1 ] .num。 } LLクエリ(LL nowti、LL根、LL、L、LL R){ もし(ツリー[ルート] .ti <= nowti) リターン・ツリー[ルート] .num。 もし(L == R) 戻り nowti / L。 INT midd =(L + R)>> 1 。 もし(ツリー[ルート<< 1 ] .ti> = nowti) 戻りクエリ(nowti、LSON)。 他 戻りクエリ(nowtiツリー[ルート<< 1 ] .ti、rson)+ツリー[ルート<< 1 ] .num。 } LL DFS(INT U、LL nowt){ // COUT << U << ENDL。 更新(X [U]、T [U]、1、1、1000000 ); LL DP1 =クエリ(nowt、1、1、1000000 )。 LL DP2 = 0、DP3 = 0 。 以下のために(INT iが= 0 ; I <G [U] .size(); I ++ ){ ノードV = G [U] [I]。 もし(nowt <= 2 * VW) 続けます。 LL TEMP = DFS(VU、nowt-2LL * VW)。 もし(TEMP> DP2) DP3 = DP2、DP2 = TEMP。 それ以外の 場合(DP3 < TEMP) DP3 = TEMP; } 更新( -X- [U]、T [U]、1、1、1000000 ); IF(U == 1)/// ルートノード、我々は時間を考慮していないので、行きます大きな リターンmaxは(DP1は、DP2である); 他 戻りMAX(DP1、DP3); } int型のmain(){ LL T; scanfの(" %D%I64d "、およびN-、&T) のための(INT I = 1 ; I <= N; I ++ ) scanfの(" %I64d"、・X [I])。 以下のために(INT iが= 1 ; I <= N; I ++ ) のscanf(" %I64d "、およびT [I])。 以下のために(INT iが= 2 ; I <= N; I ++ ){ W LL。 int型のuを。 scanf関数(" %D%I64d "、&U、&W)。 G [U] .pb(ノード{I、W})。 } のprintf(" %I64d "、DFS(1 、T))。 リターン 0 ; }