LCA (공통 조상) 문제

문제 설명

트리에서, 노드는 노드의 X (Z)의 상위 (즉, Z 깊이 노드 <노드 X), (Y)은 조상이 경우. 따라서 노드 z는 x 및 y의 공통 조상 인 방법.

그 이름이 암시 거리와 가장 가까운 공통 조상에 대한 x와 y를 들면, 소위 공통 조상.

용액 A : 최대 라벨

당신은 고열을 만들어 결과적으로, 그렇지 않으면 교환 방법을 재생되지 않습니다하지 않는

X는 상향 표시된 모든 노드를 통해 루트 노드에서 갔다.

노드가 지점을 요청하는 경우 Y는 첫 번째 노드가 발생 레이블이 노드에서 이동.

항상 최악의 복잡성을 요청하는 O입니다 (N)

해결 방법 2 : 트리 곱셈 방법

미지근한, 플레이 아에 시험 방에 매우 적합합니다 ...

우선 곱셈 알고리즘을 이해합니다. 동적 프로그래밍과 유사

복잡도 O ((N + m) 로그 N)

사전 곱셈

집합 F [X, K] 나타내고 2 × K 생성 조상. 최대 즉,이 점프 X K의 노드에 도달. 당신이 노드로 이동할 경우 단순히 우리가 그 값을 0으로 만들 존재하지 않습니다.

물론, 정의에 의해,이 그릴 수 F [X, 0] (X)의 부모이다.

많은 홉의 경우, 얻어진 K [1 logn]의 범위에 속하는 것이다. C ++에서 다음과 같이 작성해야한다

t = ( INT ) 로그 (N) / 로그 ( 2 ) + 1

그런 다음, 전사 식있다 :

F [X, K = F [F [X, K-1, K-1, 2 사람 K. 1- +2 K. 1 = 2 * 2 K. 1 = 2 K

그것은 O의 시간 복잡도를 취할 것으로 예상된다 (n 개의 logn)

보이드 BFS () { 
    q.push ( 1 ); 
    이 D [ 1 ] = 1 ;
    반면 (q.size ()) {
         INT (X) = q.front (); q.pop ();
        위한 ( INT 나 헤드 [X] =를, 난, 난 = 다음 [I]) {
             INT의 Y = 끝 [I];
            경우 (d [Y]) 계속 ; 
            D [Y] = D [X] + 1 ; 
            F [Y] [ 0 ] = X;
             ( INT J = 1 ; J <= t, J ++ ) { 
                F [Y] [J]F = [F [Y] [J = 1 ] [J = 1 ]; 
            } 
            q.push (Y); 
        } 
    } 
}

점프 공정 LCA 

상기 전처리에서, 우리는 D (깊이) 어레이와 어레이가 초기화되었는지의 F (승산)을 얻었다

우리는 가정이 D [X]> = D [Y] (그렇지 않으면 당신은 일을 교체 할 수 있습니다)

1.하자가하는 말과 같은 높이와 y로, 점프 점프 X

  어떻게 그것을 달성하기 위해? 열거. 열거에 홉의 수. 2 = 열거 점프 logN이 열거되어 1-2 0 . 왜 아직 부어? 당신이 복잡성을 줄이기 위해 가능한 한 작은으로 점프 할 횟수 때문입니다.

  노드가 Y보다 낮은 약간에 점프하는 것입니다 확인하십시오. 점프가 완료되면, 즉,하자 X = F [X, 점프]

2. 조상에게 원래 Y (X)을 나타내는 X == Y 완료 (면에 X Y 점프)의 첫 번째 단계가있는 경우에는, 다음 LCA Y는 동일하다.

3.하자가 x와 y는 모두 같은 깊이 아니라 싱크에를 유지하기 위해 함께 점프. 아직 점프를 열거하기 위해 동일한 단계를 수행합니다. 만큼 F [X, 점프]와 같이하지 오프 할당 F [Y, 점프, 동일.

샤프니스 3 단계 후 4. X 및 Y는 과거의 최종 단계를 전송해야한다. 두 후 모든 부모 노드는 LCA (X, Y)에 결합된다. 그래서이 경우에서의 LCA (X, Y) = F [X, 0]

INT LCA ( INT (X), INT의 Y) {
     경우 (d [X]> D [Y]) 스왑 (X, Y);
     ( INT I = t; I> = 0 ; 난 ... ) {
         경우 (d [F [Y] [I]]> = D [X]) Y = F [Y] [I];
        경우 (X == y)를 반환 X;    
    } 
    에 대해 ( INT I = t; I> = 0 ; 난 ... ) {
         경우 (! F [X] [I] = F [Y] [I]), X = F [X] [I]은, Y는 = F를 [Y] [I]; 
    } 
    리턴 F [X] [ 0 ]; 
}

 용도

노드의 최단 경로에있는 모든 노드의 Y 값 (X)에서 트리 요청

사실,이이 블로그를 작성하는 목적은 ...

그것을 어떻게? 사실, 단지 자연을. 즉 하나의 소스를 (직접 또는 DFS) 최단 경로를 할 루트 노드부터 시작이다. 이어서 거리 (X, Y) =는 distence (X) +는 distence (Y) - 2 *는 distence (LCA)

따라서, 최단 경로 만 O (N), 다음 LCA를 추구한다.

추천

출처www.cnblogs.com/Uninstalllingyi/p/11822227.html