倍増方法LCAを探しています
LCAはすぐに木の2点間の最短経路を見つけるために使用することができます
Oの時間複雑(nlogn)
1の#include <iostreamの> 2の#include < ストリング・H> 3の#include <アルゴリズム> 4の#include <ベクトル> 5の#include <地図> 6の#include <ビットセット> 7の#include < 設定 > 8の#include <数学。 H> 9の#include < ストリング > 10 の#if!定義(_WIN32) 11の#include <ビット/ STDC ++。H> 12 #endifの // !定義(_WIN32) 13 の#define LL長い長い 14 の#define DDダブル 15を 使用します 名前空間はstd; 16 構造体端部 17 { 18 INT に、 19 int型の重量; 20 int型の次。 21 } E [ 500005 ]。 22 int型ヘッド[ 100086 ]。 23 int型 P [ 100086 ] [ 25 ]。 24 INT深い[ 100086 ]。 25の LL DIS [ 100086 ]。 26 int型N、M。 27 int型のTOT; 28 ボイドアドオン(int型のx、int型の Y、int型Z) 29 { 30 TOT ++ 。 31 E [TOT] .TO = Y。 32 E [TOT] .weight = Z。 33 E [TOT] .next = 頭部[X]。 34 頭[X] = TOT。 35 } 36の 空隙 DFS(int型のx、int型F) 37 { 38 P [X]は[ 0 ] = Fと、 39 ディープ[X] =深い[F] + 1 。 40 のための(int型I = 1 ; (1 << I)<=深い[X]。I ++ ) 41 P [X] [I] = P [P [X] [I - 1 ] [I - 1 ]。 42 のために(int型 I =ヘッド[X]; I; I = E [I] .next) 43 { 44 INT =にE [I] .TO。 45 であれば(!へ= F) 46 { 47 DIS [に対する] = DIS [X] + E [I] .weight。 48の DFS(X、へ)。 49 } 50 } 51 } 52 int型 LCA(int型のx、int型のY) 53 { 54 であれば(深い[X] < 深い[Y]) 55 スワップ(X、Y) 56 一方(深い[X]> 深い[Y]) 57 X = P [X] [(INT)LOG2(深い[X] - ディープ[Y])]。 58 であれば(x == y)が 59 リターンY。 60 のための(int型 K =(INT)LOG2(深い[X]); K> = 0 ; k-- ) 61 であれば(!P [X] [K] = P [Y] [K]) 62 { 63 X = P [X] [K]。 64 、Y = P [Y] [K]。 65 } 66 リターン P [X] [ 0 ]。 67 } 68 のint main()の 69 { 70 CIN >> N >> M。 71 のために(int型 i = 1 ; iがN <; Iは++ ) 72 { 73 のint X、Y、Zと、 74 CIN >> X >> Y >> Z。 75 追加(X、Y、Z)。 76 追加(X、Y、Z)。 77 } 78 DFS(1、0 ); 79 のためには、(int型 I = 1 ; I <= M; iは++ ) 80 { 81 のint X、Y。 82 CIN >> X >> Y。 83 INT C = LCA(X、Y) 84 COUT << DIS [X] + DIS [Y] - 2つの * DIS [C] << ENDL。 85 } 86 リターン 0 。 87 }