トピックリンクします。https://vjudge.net/problem/HDU-3534
問題の意味:木、木要求最長距離(直径)、およびそのような距離の数所与。
考える:ちょうど直径場合は、2つのDFSを使用することができます。しかし、今uはuが最も長い距離にリーフノードをルートとするサブツリーに記録されているDP1 [U]で、最長距離の番号を必要とする、DP2は、[U]は、これらの二つの最長の距離、比較の数を表します。維持しやすいです。DFS回答更新プロセス、ANS1で表されるツリーの直径は、ANS2は、直径の数、DP1 [V] + W + DP1 [U]> ANS1更新を示しています。
ACコード:
書式#include <cstdioを> する#include <アルゴリズム> 使用して 名前空間はstdを、 const int型 MAXN = 1E4 + 5 。 typedefの長い 長いLL。 int型N、CNT、ヘッド[MAXN]。 【MAXN] ANS1、ANS2、DP1 [MAXN]、DP2 LL。 構造体ノード{ int型NEX、W、V、。 }エッジ[MAXN << 1 ]。 ボイド ADDE(int型 U、int型、VをINT W){ エッジ[ ++ CNT] .V = V。 エッジ[CNT] .W = W。 エッジ[CNT] .nex = 頭部[U]。 ヘッド[U] = CNT。 } ボイド DFS(int型、Uをint型FA)を{ DP1 [U] = 0、DP2 [U] = 1 。 以下のために(int型 ; I I = I =ヘッド[U] {エッジ[I] .nex) のint V =エッジ[I] .V、W = エッジ[I] .W。 もし(== FA V)続けます。 DFS(V、U); INT TMP = DP1 [V] + W。 もし(TMP + DP1 [U]> ANS1){ ANS1 = TMP + DP1 [U]。 ANS2 = DP2 [U] * DP2 [V]。 } そう であれば(TMP + DP1 [U] == ANS1){ ANS2 + = DP2 [U] * DP2 [V]。 } もし(TMP> DP1 [U]){ DP1 [U] = TMP。 DP2 [U] = DP2 [V]。 } そう であれば(TMP == DP1 [U]){ DP2 [U] + = DP2 [V]。 } } } INT (){主 ながら(〜のscanf(" %d個"、&N)){ CNT = ANS1 = ANS2 = 0 。 以下のために(int型 i = 1 ; iは= N <; ++ I) ヘッド[I] = 0 ; 以下のために(int型 i = 1 ; iがn <; ++ I){ int型、U、V、W。 scanf関数(" %D%D%D "、およびuは、&V、およびW) ADDE(U、V、W)。 ADDE(V、U、W)。 } DFS(1、0 ); printf(" %LLD%LLD \ n " 、ANS1、ANS2)。 } リターン 0 ; }
ちなみに、コードのみ必要な直径のDFSで二回添付:
書式#include <cstdioを> する#include <アルゴリズム> 書式#include <CStringの> 使用して 名前空間はstdを、 typedefの長い 長いLL。 const int型 MAXN = 1E4 + 5 。 int型N、CNT、ヘッド[MAXN]。 LLのDP1 [MAXN]、DP2 [MAXN]。 構造体ノード{ int型NEX、W、V、。 }エッジ[MAXN << 1 ]。 ボイド ADDE(int型 U、int型、VをINT W){ エッジ[ ++ CNT] .V = V。 エッジ[CNT] .W = W。 エッジ[CNT] .nex = 頭部[U]。 ヘッド[U] = CNT。 } ボイド DFS(int型、Uをint型FA)を{ DP1 [U] = 0 。 int型フラグ= 0 。 以下のために(int型 ; I I = I =ヘッド[U] {エッジ[I] .nex) のint V =エッジ[I] .V、W = エッジ[I] .W。 もし(== FA V)続けます。 フラグ = 1 。 DFS(V、U); もし(DP1 [V] + W> DP1 [U]){ DP1 [U] = DP1 [V] + W。 DP2 [U] = DP2 [V]。 } } もし DP2 [U] =(フラグ!)U。 } INT (){主 ながら(〜のscanf(" %d個"、&N)){ CNT = 0 ; 以下のために(int型 i = 1 ; iは= N <; ++ I) ヘッド[I] = 0 ; 以下のために(int型 i = 1 ; iがn <; ++ I){ int型、U、V、W。 scanf関数(" %D%D%D "、およびuは、&V、およびW) ADDE(U、V、W)。 ADDE(V、U、W)。 } DFS(1、0 ); INT TMP = DP2 [ 1 ]。 DFS(TMP、0 ); printf(" %LLDする\ n " 、DP1 [TMP])。 } リターン 0 ; }