1+ import java .util .*;
2+ import java .io .*;
3+
4+ public class Main {
5+ static int N , M ;
6+ static ArrayList <Integer >[] tree ;
7+ static boolean [] visited ;
8+ static int [][] parent ;
9+ static int [] depth ;
10+ static int kMax = 0 ;
11+
12+ public static void main (String [] args ) throws IOException {
13+ BufferedReader br = new BufferedReader (new InputStreamReader (System .in ));
14+ StringTokenizer st ;
15+
16+ // 초기화
17+ N = Integer .parseInt (br .readLine ());
18+ tree = new ArrayList [N +1 ];
19+ for (int i =0 ; i <=N ; i ++) {
20+ tree [i ] = new ArrayList <>();
21+ }
22+
23+ // 입력
24+ for (int i =0 ; i <N -1 ; i ++) {
25+ st = new StringTokenizer (br .readLine ());
26+ int s = Integer .parseInt (st .nextToken ());
27+ int e = Integer .parseInt (st .nextToken ());
28+ tree [s ].add (e );
29+ tree [e ].add (s );
30+ }
31+
32+ // bfs용 변수 초기화
33+ depth = new int [N +1 ];
34+ visited = new boolean [N +1 ];
35+ int temp = 1 ;
36+ while (temp <= N ) {
37+ temp *= 2 ;
38+ kMax ++;
39+ }
40+
41+ // parent
42+ parent = new int [kMax +1 ][N +1 ];
43+ BFS (1 );
44+ for (int k =1 ; k <=kMax ; k ++) {
45+ for (int n =1 ; n <=N ; n ++) {
46+ parent [k ][n ] = parent [k -1 ][parent [k -1 ][n ]];
47+ }
48+ }
49+
50+ // 질의
51+ M = Integer .parseInt (br .readLine ());
52+ for (int i =0 ; i <M ; i ++) {
53+ st = new StringTokenizer (br .readLine ());
54+ int a = Integer .parseInt (st .nextToken ());
55+ int b = Integer .parseInt (st .nextToken ());
56+ System .out .println (LCA (a ,b ));
57+ }
58+ }
59+
60+ static int LCA (int a , int b ) {
61+ if (depth [a ] > depth [b ]) {
62+ int temp = a ;
63+ a = b ;
64+ b = temp ;
65+ }
66+
67+ // depth 맞추기
68+ for (int k =kMax ; k >=0 ; k --) {
69+ if (Math .pow (2 ,k ) <= depth [b ] - depth [a ]) {
70+ if (depth [a ] <= depth [parent [k ][b ]]) {
71+ b = parent [k ][b ];
72+ }
73+ }
74+ }
75+
76+ // 조상 찾기
77+ for (int k =kMax ; k >=0 ; k --) {
78+ if (parent [k ][a ] != parent [k ][b ]) {
79+ a = parent [k ][a ];
80+ b = parent [k ][b ];
81+ }
82+ }
83+
84+ return a !=b ? parent [0 ][a ] : a ;
85+ }
86+
87+ static void BFS (int root ) {
88+ Queue <Integer > q = new LinkedList <>();
89+ q .add (root );
90+ visited [root ] = true ;
91+ depth [root ] = 0 ;
92+
93+ while (!q .isEmpty ()) {
94+ int now = q .poll ();
95+ for (int next : tree [now ]) {
96+ if (!visited [next ]) {
97+ q .add (next );
98+ visited [next ] = true ;
99+ parent [0 ][next ] = now ; // 부모 노드 저장
100+ depth [next ] = depth [now ] + 1 ;
101+ }
102+ }
103+ }
104+ }
105+ }
0 commit comments