P1967の運送
最大ツリー経路+最小乗算演算子にまたがります
一般クラスカルのように下降するエッジをクラスカルときスパニングツリーは最大であります
LCAは、言った、他のサン・オペレーションのテンプレートと乗算されたよう
また、前処理パス重み最小値または最大値と権利情報などの時、このように記録することができる、得られるように右ツリーOの2点間の経路(LOGN)時間最大値、最小値と題されています
書式#include <iostreamの> の#include <cstdioを> する#include <キュー> の#include <CStringの> の#include <cmath> の#include <スタック> の#include <アルゴリズム> 使用して 名前空間はstdを、 #defineっ長い長 の#define RGレジスタ のconst int型 N = 100000 + 5、M = 500000 + 5、INF = 0x3f3f3f3f、P = 19650827 。 INTのN、M、Q。 INT DEP [N]、P [N] [ 25 ]、[N] W [ 25 ]。 テンプレート < クラス T> ボイド RD(T&X){ X = 0。INT W = 0。CHAR CH = 0 。 しばらく W | = CH ==(isdigit(CH)!)' - '、CH = getchar関数(); 一方、(isdigit(CH))X =(X << 1)+(X << 3)+(CH ^ 48)、CH = GETCHAR()。 X?= W - X:X; } int型のヘッド[N]、TOT = 0 、ANS。 構造体のエッジ{ int型V、NXT、W;} E [M]。 空隙追加(int型 U、int型 V、INT W){ E [ ++ TOT =(エッジ){V、ヘッド[U]は、W};頭部[U]は= TOT。 } INT F [N]。 構造体ノード{ int型U、V、W。 } ND [M]。 ブール CMP(ノードA、ノードB)は、{ 戻る AW> BW;} int型の検索を(INT X){ リターン:F [X] = [X] == X X F 、検索(F [X])} ボイドクラスカル(){ int型の CNT = 0 。 以下のために(RGのINT i = 1 ; iが<= N; ++ I)F [I] = I。 用(RG用のint i = 1 ; I <= M ++、U、V、W {I) U = ND [i]は.U、V = ND [I] .V、W = ND [i]は.W ; 場合(見つける(U)=!見つける(V)){ F [F [U] = F [V]。 ++ CNT; (Uは、V、W)、追加(V、U、W)。 もし(CNT == N- 1)ブレーク。 } } } ボイド DFS(int型U)を{ ため(int型 V、I =ヘッド[U]; I; I = E [I] .nxt){ V = E [I] .V。 もし(!DEP [V]){//未走过 DEP [V] = DEP [U] + 1 。 P [V] [ 0 ] = U。 [V]、W [ 0 ] = E [I] .W。 DFS(V); } } } ボイドビルド(){ 用(RG のint i = 1 ; I <= N; ++ I){ 場合(!{DEP [i])と DEP [I] = 1 。 P [I] [ 0 ] = 0 ; DFS(I); } } DFS(1)。//连起来の ため(int型 i = 1 ; iは<= 20 ; I ++ ) のための(INT J = 1 ; J <= nであり、j ++ ){ P [j]は[I] = P [P [j]は[I- 1 ] ] [I- 1 ]。 W [J] [I] =分(W [j]は[I- 1 ]、W [P [j]は[I- 1 ]] [I- 1 ])。 } } int型(LCAをINT A、INT B){ ANS = INF。 もし(DEP [A]> DEP [B])スワップ(B) 以下のための(int型私は= 20、I> = 0 ; - I){ 場合(DEP [P [B] [I] <DEP [A])続けます。 ANS =分(ANS、W [B] [I]); B = P [B] [I]。 } もし(== b)は戻りANS。 以下のために(int型 iは= 20、I> = 0 ; - I){ 場合(P [A] [I] == P [B] [i])と続けます。 ANS = 分(ANS、分([A]、W [i]は、[I])[B] W)。P = [A] [I]、B = P [B] [I]。 } ANS =分(ANS、分([A] [W 0]、W [B] [ 0 ])); 戻るANSを。 } int型のmain(){ // freopenは( "in.txt"、 "R"、STDIN)。 memset(DEP、0、はsizeof (DEP))。 memsetの(p、0、はsizeof (P))。 RD(n)は、RD(M)。 int型U、V、W; 用(RG int型 I = 1 ; I <= M ++ {I) RD(U)、RD(V)、RD(W)。 ND [I] = (ノード){U、V、W}。 } ソート(ND + 1、ND + 1 + M、CMP)。 クラスカル(); ビルド(); RD(Q)。 用(RG int型 I = 1 ; I <= Q ++ {I) RD(U)、RD(V)。 場合(見つける(U)=(v)を見つける!)のprintf(" -1です\ n " ); 他のprintf(" %d個の\ nを" 、LCA(U、V)); } 戻り 0 。 }