[11438번] 최소 공통 조상 구하기 (트리, 제곱수 LCA, LCA 시간초과)

2023. 3. 24. 15:38·Coding Test/Tree
728x90
 

11438번: LCA 2

첫째 줄에 노드의 개수 N이 주어지고, 다음 N-1개 줄에는 트리 상에서 연결된 두 정점이 주어진다. 그 다음 줄에는 가장 가까운 공통 조상을 알고싶은 쌍의 개수 M이 주어지고, 다음 M개 줄에는 정

www.acmicpc.net

 

 

분석

 

최소 공통 조상 빠르게 구하기 (트리, 제곱수 LCA, LCA 시간초과)

최소 공통 조상 빠르게 구하기 서로 깊이를 맞춰주거나 같아지는 노드를 찾을 때 기존에 한 단계씩 올려주는 방식에서 2ᵏ씩 올라가 비교하는 방식 기존에 자신의 부모 노드만 저장해 놓던 방식

karla.tistory.com

 

풀이

"""
두 노드 쌍 M개 LCA 구하기

노드의 개수 N(2~100,000)
N-1줄 트리상 연결된 두 노드
가장 가까운 공통 조상을 알고 싶은 쌍의 개수 M(1~100,000)
M줄 노드쌍

일반적인 LCA구하기 -> 시간초과
제곱수 형태를 이용한 빠르게 최소 공통 조상 구하기

"""
import sys
from collections import deque
input = sys.stdin.readline
print = sys.stdout.write

# 수의 개수
N = int(input())

# 트리 데이터 저장
tree = [[0] for _ in range(N + 1)]

for _ in range(0, N - 1):
    # 인접 리스트에 트리 데이터 저장
    s, e = map(int, input().split())
    tree[s].append(e)
    tree[e].append(s)

# 노드 깊이 리스트
depth = [0] * (N + 1)

# 방문체크 저장 리스트
visited = [False] * (N + 1)

temp = 1
kmax = 0 # 최대 가능 높이
while temp <= N:
    temp <<= 1 # 변수의 값을 왼쪽으로 지정된 비트 수 만큼 이동,  n << m : n * 2의 m승
    kmax += 1

# 노드 조상 리스트
parent = [[0 for j in range(N + 1)] for i in range(kmax + 1)]

def BFS(node):
    queue = deque()
    
    # 큐 자료구조에 출발 노드 넣기
    queue.append(node)
    
    # 현재 노드 방문 기록
    visited[node] = True
    
    level = 1 # 트리 깊이
    now_size = 1 # 현재 깊이에서 트리 크기
    
    count = 0
    while queue:
        
        # 큐에서 노드 데이터 가져오기
        now_node = queue.popleft()
        
        for next in tree[now_node]: # 현재 노드와 연결된 노드 탐색
            if not visited[next]:
                visited[next] = True
                # 큐에 데이터 삽입
                queue.append(next)
                # 부모 노드 저장
                parent[0][next] = now_node
                # 노드 현재 깊이 저장
                depth[next] = level
                
        count += 1
        if count == now_size: # 현재 깊이의 모든 노드 방문
            count = 0
            # 바로 아래 단계 트리 노드 개수 저장
            now_size = len(queue)
            # 현재 depth 1 wmdrk
            level += 1


BFS(1) # 깊이와 부모 노드 저장

for k in range(1, kmax + 1): # 2^k번째 부모 노드 계산 및 저장
    for n in range(1, N + 1): # 노드 개수만큼 반복
        # 점화식 
        parent[k][n] = parent[k - 1][parent[k - 1][n]]
        

def LCA(a, b):
    if depth[a] > depth[b]:  # 더 깊은 depth가 b가 되도록
        temp = a
        a = b
        b = temp
        
    # 두 노드의 depth 맞추기
    for k in range(kmax, -1, -1):
        if pow(2, k) <= depth[b] - depth[a]:
            if depth[a] <= depth[parent[k][b]]:
                b = parent[k][b]

    # 두 노드의 같은 조상이 나올 때까지 각 노드를 부모 노드로 변경
    for k in range(kmax, -1, -1):
        if a == b: break
        if parent[k][a] != parent[k][b]:
            a = parent[k][a]
            b = parent[k][b]

    LCA = a
    if a != b:
        LCA = parent[0][LCA]
    return LCA

M = int(input())
for _ in range(M):
    a, b = map(int, input().split())
    print(str(LCA(a, b)))
    print("\n")

 

 

 

 

728x90
저작자표시 (새창열림)
'Coding Test/Tree' 카테고리의 다른 글
  • 트리 순회(전위 순회, 중위 순회, 후위 순회), DFS, 재귀
  • [2042번] 구간합 구하기 (세그먼트 트리, 리프노드, 값 변경)
  • 최소 공통 조상 빠르게 구하기 (트리, 제곱수 LCA, LCA 시간초과)
  • 세그먼트 트리, 인덱스 트리, 구간합
Karla Ko
Karla Ko
𝘾𝙤𝙣𝙩𝙞𝙣𝙪𝙤𝙪𝙨𝙡𝙮 𝙄𝙢𝙥𝙧𝙤𝙫𝙞𝙣𝙜, 𝘾𝙤𝙣𝙨𝙩𝙖𝙣𝙩𝙡𝙮 𝘿𝙚𝙫𝙚𝙡𝙤𝙥𝙞𝙣𝙜 𝙔𝙚𝙨!
    250x250
  • Karla Ko
    karlaLog
    Karla Ko
  • 전체
    오늘
    어제
    • Total (467)
      • Spring (19)
      • JPA (4)
      • Cloud & Architecture (15)
        • Kubernetes (5)
        • Docker (3)
        • MSA (2)
        • GCP (1)
        • AWS (4)
      • Devops (1)
      • Message Queue (4)
        • Kafka (2)
        • RabbitMQ (2)
      • Git (4)
      • DB (4)
      • Java (9)
      • Python (4)
      • CS (11)
        • OS (8)
        • Network (2)
        • Algorithm (1)
      • Coding Test (392)
        • programmers (156)
        • Graph (43)
        • DP (37)
        • Search (31)
        • Tree (13)
        • Data Structure (26)
        • Combination (12)
        • Implement (18)
        • Geedy (23)
        • Sort (7)
        • Math (21)
        • geometry (2)
  • 블로그 메뉴

    • 홈
  • 링크

  • 공지사항

  • 인기 글

  • 태그

    스택
    파이썬
    LIS
    힙
    Algorithm
    알고리즘
    플로이드워셜
    큐
    그리디
    자료구조
    백준
    BFS
    구현
    동적계획법
    그래프
    프로그래머스
    다익스트라
    최소신장트리
    이분탐색
    DFS
    트리
    최단거리
    구간합
    최대공약수
    정렬
    덱
    DP
    재귀
    월간코드챌린지
    조합
  • hELLO· Designed By정상우.v4.10.3
Karla Ko
[11438번] 최소 공통 조상 구하기 (트리, 제곱수 LCA, LCA 시간초과)
상단으로

티스토리툴바