テンプレートのタイトルリンク:
https://www.luogu.com.cn/problem/P3379
参考ブログ:
https://www.luogu.com.cn/blog/morslin/solution-p3379
コード:
書式#include <iostreamの> 書式#include <stdio.hに> する#include <stdlib.h>に含ま する#include < 文字列の.h> の#include <スタック> 使用して 名前空間はstdを、 const int型 MAXN = 5E5 + 5 。 整数N、M、S。 int型のヘッド[MAXN]、TOT1。 INTの DEP [MAXN]、F [MAXN] [ 21 ]、LG [MAXN]。 構造体のノード { int型の次に。 } E [MAXN * 3 ]。 無効アドオン(int型のx、int型のY) { E [TOT1] .TO = Y。 E [TOT1] .next = 頭部[X]。 ヘッド[X] = TOT1 ++ 。 } 無効 DFS(int型のu、int型FA) { DEP [U] = DEP [FA] + 1 。 F [U] [ 0 ] = FA。 用(INTは iは= 1 ; I <= LG [DEP [U]; I ++ ) F [U] [I] = F [F [U] [I- 1 ]] [I- 1 ]。 以下のための(int型!; -私は= [U]私は頭を= 1 ;私は= E [i]の.nextを) { int型、V = E [i]の.TO。 もし(V!= FA) DFS(V、U); } } int型 LCA(int型 A、int型のB) { もし(DEP [A] < DEP [B]) スワップ(B) 一方、(DEP []> DEP [B])= F [A] [LG [DEP [A] -dep [B]] - 1 ]。 場合(== b)は返します。 用(INT K = LG [DEP [A]] - 1 ; K> = 0 ; k-- ) であれば(!F [A] [K] = F [B] [K])= F [A] [K]、B = F [B] [K]。 リターン F [A] [ 0 ]。 } int型のmain() { scanf関数(" %D%D%D "、&N、&M&S)。 memsetの(頭、 - 1、はsizeof (ヘッド))。 以下のために(INT iが= 1 ; I <N; I ++ ) { INT X、Y。 scanf関数(" %D%D "、およびX&Y)。 (x、y)を加えます。 (Y、X)を追加します。 } 以下のために(INT iが= 1 ; I <= N; I ++ ) LG [I] = LG [I- 1 ] +(1 << LG [I- 1 ] == I)。 DFS(S、0 ); 以下のために(INT iが= 1 ; I <= M; I ++ ) { INT X、Y。 scanf関数(" %D%D "、およびX&Y)。 printf(" %D \ n " 、LCA(X、Y))。 } リターン 0 ; }