자세한 // 참조 https://www.cnblogs.com/zwfymqz/p/7795299.html
// 블로거 : 연애 사건에서이 볼모하는 https://www.cnblogs.com/zwfymqz/을
// 로스 밸리 P3379 최근 공통 조상 링크 https://www.luogu.org/problem/P3379
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 #INCLUDE <cstdio> 2 #INCLUDE <CString을> 3 #INCLUDE <알고리즘> 4 이용한 스페이스 성병; 5 6 CONST의 INT MAXN 1E5 + = 10 ; 7 8 구조체 노드 { 9 의 INT V 다음; 10 } 에지 [MAXN]; 11 (12) INT의 헤드 [MAXN]; 13 의 INT NUM = 1 ; 14 인라인 공극 의 add_edge ( INT (X), INT의 Y) { 15 가장자리 [NUM] .V = Y; 16 가장자리 [NUM] 다음 내용 = 헤드 [X]; 17 헤드 [X] = NUM ++ ; 18 } 19 20 INT의 F [MAXN] [ 21 ]; 21 INT 깊은 [MAXN]; 22 INT의 N, m, 루트; (23) 보이드 DFS ( INT의 현재) { 24 대 ( int로 I = 헤드 [CUR를] 난 =! - 1 ] I = 가장자리 [i]는 다음 내용) { 25 일 경우 (! {깊은 [에지 [I] .V]) 26 깊이 [에지 [I] .V = 깊은 [CUR] + 1 ; 27 F [에지 [I] .V]0 ] = CUR; 28 DFS (에지 [I] .V); 29 } 30 } 31 } 32 33 공극 PRE () { 34 대 ( INT의 J = 1 ; J <= 19 ; ++ j)는 { (35) 에 대해 ( int로 I = 1 ; i가 = N <; ++ I) { 36 F [I]은 [J]는 F를 = F [I] [J = 1 ] [J = 1 ]; 37 } 38 } 39 } 40 41 INTLCA ( INT의 X, INT의 Y) { 42 의 경우 (깊이 [X] < 깊은 [Y]) 스왑 (X, Y); (43) 에 대한이 ( int로 난 = 19 , I> = 0 - I) { 44 의 경우 (깊이 [F [X] [I]]> = 깊은 [Y]) { 45 , X = F [X] [I]; 46 } 47 } 48 의 경우 (X == y)를 반환 X; (49) 에 대한이 ( int로 난 = 19 , I> = 0 - I) { 50 하다면([X] [I] = F! {F [Y] [I]) (51) , X = F [X] [I]; (52) Y = F [Y] [I]; 53 } 54 } 55 리턴 F [X] [ 0 ]; 56 } 57 58 INT 의 main () { 59 memset 함수 (헤드 - 1 , 를 sizeof (헤드)); 60 는 scanf ( " % D % D % D " , 및 N, m, 루트); 61 INT의 X, Y; 62 대 ( int로 = 1을 0 ]! = N- 난1 ; ++ I) { 63 는 scanf ( " % d 개 %의 D ' , X, Y); 64 의 add_edge (X, Y); 65 의 add_edge (Y, X); 66 } 67 깊은 [루트] = 1 ; 68 DFS (루트); 69 PRE (); 70 대 ( int로 = 1을 0 , I = N]! ++ I) { 71 는 scanf ( " % d 개 %의 D ' , X, Y); 72 의 printf ( " % D \ 없음 " , LCA (X, Y)); 73 } 74 반환 0 ? 75 }