彼は分析の本質に落ちた....(も慎重にタイトルを読んで)
慎重にタイトルを読んだ後、我々は、赤色エッジは、通信ブロックとリーフノード(または2つのリーフノード)を接続することができることを見出しました。
次に、もし法的な状態であれば、すべてのエッジのルートである点は、青色息子として形成されている場合にのみ、[X] - > X-> FA [X]
そして、このためな性質のため、我々は木-DPことができます。
$ 1 $ルート、$ F [x]は$ $ X $表す$ X $の中点の青側は$ G、サブツリーのルートである場合に最大値である[X] $を作ることは、時間で最大値が中間点ではない表します。
次いで、ルートは、$ 1 $でない場合、方法ルートDPへの転送を変更することにより、それは次の最小値と共に最小記録/転送を必要とします。
#include <cstdioを> する#include <ストリング> の#include <CStringの> する#include <アルゴリズム> の#define N 200007 の#define 1000000000 INF 名前空間stdを使用。 ボイドsetIO(文字列s) { = S +の文字列"に"。 = S +アウト文字列"アウト。"; freopenは(in.c_str()、 "R"、標準入力)。 // freopenは(out.c_str()、 "W"、STDOUT)。 } INTエッジ、N、ANS。 INT F [N]、G [N]、HD [N]、[N << 1]、NEX [N << 1]、ヴァル[N << 1]、F1 [N]、F2 [N]。 ボイド追加(INT U、V INT、INT C) { NEX [++エッジ] = HD [U]、HD [U] =縁、[エッジ]へ= V、ヴァル[縁] = C。 } 無効DFS(int型のuを、 (; iはNEX [I] = [U] INT I = HD)用 { int型V =に[I]を、 (V == FF)は継続であれば、 DFS(V、U); G [U] + = MAX(G [V]、F [V] +ヴァル[I])。 } のための(INT I = HD [U]; iが、iはNEX [I] =) { int型V =に[I]を、 (V == FF)は継続であれば、 F [U] = MAX(F [U]、G [U] -max(G [V]、F [V] +ヴァル[I])+ G [V] +ヴァル[I])。 INT TMP = G [V] +ヴァル[I] -max(G [V]、F [V] +ヴァル[I])。 IF(TMP> F1 [U])F [U] = F1 [U]、F1 [U] = TMP。 そうであれば(TMP> F2 [U])F [U] = TMP。 } } ボイドDFS2(INT U、INT FF) { ANS = MAX(ANS、G [U])。 (; iはNEX [I] = [U] INT I = HD)用 { int型V =に[I]を、 (V == FF)は継続であれば、 GU INT = G [U] -max(G [V]、G [V] + F1 [V] +ヴァル[i])と、FU。 IF(F1 [U] == G [V] +ヴァル[I] -max(G [V]、G [V] + F1 [V] +ヴァル[I]))FU = F2 [U]。 他FU = F1 [U]; G [V] + = MAX(GU、GU + FU +ヴァル[I])。 FU = GU +ヴァル[I] -max(GU、GU + FU +ヴァル[I])。 IF(FU> F1 [V])F [V] = F1 [V]、F1 [V] = FU。 そうであれば(FU> F2 [V])F [V] = FU。 DFS2(V、U); } } int型のmain() { // setIO( "入力")。 INT I、J、X、Y、Z。 scanf関数( "%のD"、&N); scanf関数( "%D%D%D"、およびX&Y、およびZ)、(X、Y、Z)を追加し、(X、Y、Z)を追加;(; I <N ++ iは= 1)のための ANS = -inf。 DFS(1,0)。 printf( "%dの\ n"は、ANS)。 0を返します。 }