書式#include <iostreamの> の#include <アルゴリズム> 書式#include <cstdioを> する#include < 文字列 > の#include <CStringの> 使用して 名前空間はstdを、 typedefの長い 長いLL。 const int型 N = 100010 ; const int型 INF = 0x3f3f3f3f 。 INT H [N]、NE [N]、IDX。 int型ST [N]; int型のn; int型TOT; 構造体ノード{ int型、U。 int型V; int型に、 }。 ノードE [ 2 * N]。 ボイド追加(int型、int型B){ E [IDX] .U = 。 E [IDX] .V = B。 E [IDX] .TO = H [A]。 H [A] = IDX ++ 。 } ボイド DFS(INT U){ int型I。 もし(ST [U]) のリターン; ST [U] = 真; TOT ++ ; 以下のために(私はH [U] =; iが=! - 1 ; iが= E [I] .TO) DFSの(e [i]の.V)。 } int型のp、TMP; INT DFS1(INT U INT前に、INT N){ int型のI。 int型でも= 0 ; int型の合計= 0 ; INT年= 0 ; 用 - ;(!および= iはH [U] = 1 ; iが= {E [I] .TO) のint J = E [I] .V。 もし(jは== ん) 続けます。 すべて = DFS1(J、U、N)。 ANS = MAX(偶数年); 和 + =すべて; } ANS = MAX(ANS、N-sum- 1 )。 もし(ANS < {TMP) TMP = ANS。 P = U; } 戻り値の和+ 1 。 } LL RES。 INT DFS2(INT U、INT FA){ int型I。 int型、T = 0 ; int型の合計= 0 ; 以下のために(!; I = - iがH [U] = 1 ; iが= E [I] .TO){ int型 J = E [I] .V。 もし J(==FA) 続けます。 T = DFS2(J、U)。 RES + =(1LL * T)*(1LL *(N T))。 合計 + = T; } 戻り値の和+ 1 。 } int型のmain(){ scanf関数(" %のD "、&N) memsetの(H、 - 1、はsizeof H)。 int型私は、 int型U、Vを、 ための式(I = 0、I <N- 2、I ++ ){ scanf関数は(" %D%D "、&U、およびV)。 アドオン(U、V); (V、U)を追加します。 } INT ROOT1、root2、N1、N2、 ための式(I = 1 ; iが<= N; iが++ ){ 場合(!ST [I]){ TOT = 0 。 DFS(I); もし(iは== 1 ){ ROOT1 = 1 。 N1 = TOT; } 他{ root2 = I。 N2 = TOT; } } } int型 G1、G2; TMP = infファイル。 DFS1(ROOT1、 - 1 、N1)。 G1 = P; TMP = infファイル。 DFS1(root2、 - 1 、N 2)。 G2 = P; (G1、G2)を追加します。 (G2、G1)を追加します。 DFS2(1 - 1 )。 printf(" %のLLD \ n " 、RES)。 リターン 0 ; }
これは、木問題は、間の問題の木のDPの動的プログラミングの本質に焦点を当てている解決することです。
重力の解決DFSの中心部に接続され、マージされたツリーと距離を解くことによって、2つのツリーです
そして、左ノードからの生成物および(2点の各経路の両側に、この寄与を考慮して)各エッジの右ノード数として表さ
ツリーの重心として定義される点のポイント部ユニコムサブツリーの最大数最小点の後に除去されます。
自然:
重心両方が重力の隣接する二つの中心が存在する場合であろう。1.各ツリーの重心は、最大2つを有しています。
接続の重心を合わせた2つのツリー内の2つのツリーの重心2.中心。