定義:
ツリーが与えられると、ツリーは、各エッジの重み、二点及び縁を結ぶ経路の右側への2つのツリーの間に画定された距離を有します。ツリーの直径は、2点を結ぶ経路がツリーの最長鎖と呼ばれ、ツリー内の最も遠い2つのノード間の距離と呼ばれています。後者はまた、経路はその代わりにすることができる、すなわち直径値は概念であり、直径は一般的に呼ばれてもよいです
見つけるための2つの直径木法は通常あり、時間複雑度はO(n)です。我々は、N N-1点エッジストリップによって与えられ、ネイバーテーブルに格納された有向グラフツリーの形をとります。
方法A:DPツリー
利点:1つの簡単なコード
図2は、現在の点をルートと各サブツリーの最も長い鎖を処理することができます。
短所:簡単に直径2つのエンドポイントを決定。
アクトII:二回DFS(BFS)
利点:特定のノードの直径を計算することは容易。
短所:唯一の直径との距離を求めることができます。
それらを繰り返さないことが証明、それはオンラインもありますが、比較的簡単です。
タイトル戦は、裸であるPOJ 1985牛マラソン
書式#include <iostreamの> の#include <cstdioを> する#include <CStringの> の#include <キュー> std名前空間を使用しました。 #define Rレジスタ の#defineが長い長っ )(インラインLLリード { チャーCC = GETCHAR(); LL AA = 0。 一方(CC < '0' || CC> '9')CC = GETCHAR()。 (CC> = '0' && CC <= '9')、一方 {; CC = GETCHAR()AA =(AA << 3)+(AA << 1)+(CC ^ 48)} 戻りAA。 } のconst int型N = 1E6。 [N << 1]、NXT [N << 1]、エッジ[N << 1]、最初の[N]版のint TOT、。 インラインボイド追加(int型のx、int型のY、int型Z) { 版[++ TOT = Y; NXT [TOT =最初の[X]。 エッジ【TOT] = zは、最初の[X] = TOT;返します。 } 、N INT [N] F、ANS。 {(; iはi = NXT [I] R iは=最初の[x]は、V INT)のために 、V =版[i]は、(V == FA)続行。 DP(V、X) F [0] = MAX(F [0]、F [X] + F [V] +エッジ[I])。 F [X] = MAX(F [X]、F [V] +エッジ[I])。 } } DIS [N]、PI、PJをint型、 ボイドDFS(int型のx、int型FA) { ための(R int型のI =最初の[X]、V; I; I = NXT [I]){ V =版[I];(V == FA)が続けば、 DFS(V、x)は、DIS [V] [I] DIS [X] +エッジを=。 IF(DIS [PJ] <DIS [V])PJ = V。 } } キュー<整数>チー; ボイドBFS(INT X) { memsetの(DIS、-1、はsizeof(DIS)); DIS [X] = 0; qi.push(X)。 (!qi.empty()){一方 INT U = qi.front(); qi.pop()。 以下のための(R int型のI =最初の[U]、V; I; I = NXT [I]){ V =版[I]; IF(DIS [V] = - 1!)続けます。 qi.push(V)、DIS [V] [I] DIS [U] +エッジを=。 (DIS [V]> DIS [PJ])であればPJ = V。 } } } )(メインINT { N = read()は、READ()。 (Rは、I = 1、X、Y、Zをint型、iがN <; ++ i)のために{ X =読み取る(); Yが読み出さ=(); Z =を読み取ります()。 (X、Y、Z)を追加し、(X、Y、Z)を追加します。 } F [0] = 0; DP(1,1); ANS = F [0]; // DP DIS [1] = 0; PJ = 1; DFS(1,1); PI = PJ。 DIS [PI] = 0; DFS(PI、PI); ANS = DIS [PJ]; // DFS PJ = 1; BFS(1); PI = PJ。 BFS(PI); ANS = DIS [PJ]; // BFS のprintf( "%d個の\ n"、ANS)。 }