[11437] 최소 공통 조상 (트리, 일반 LCA)

2023. 6. 5. 16:58·Coding Test/Tree
728x90
 

11437번: LCA

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

www.acmicpc.net

 

분석

최소 공통 조상

  • 임의의 두 노드를 선택 했을 때 두 노드가 각각 자신을 포함해 거슬러 올라가면서 부모 노드를 탐색할 때 처음 공통으로 만나게 되는 부모 노드(lowest common acestor)

최소 공통 조상 구하기

  • 루트 노드에서 탐색을 시작해각 노드의 부모 노드와 깊이 저장 (DFS/BFS로 탐색)
  • 선택된 두 노드의 깊이가 다른 경우, 더 깊은 노드의 노드를 부모 노드로 1개씩 올려주면서 같은 깊이로 맞춤. 두 노드가 같으면 해당 노드가 공통 조상이므로 탐색 중단
  • 깊이가 같은 상태에서 동시에 부모 노드로 올라가면서 두 노드가 같은 노드가 될 때까지 반복, 이 때 처음 만나는 노드가 최소 공통 조상

 

풀이

import sys
input = sys.stdin.readline

n = int(input())  # 수의 개수
tree = [[] 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)  # 노드 깊이 리스트
parent = [0]*(n+1) # 노드 조상 리스트
visited=[False]*(n+1)  # 방문체크 저장 리스트

def BFS(node):
    queue = [node]
    visited[node] = True  # 현재 노드 방문 기록
    while queue:
        # 큐에서 노드 데이터 가져오기
        now_node = queue.pop(0)
        for next in tree[now_node]:  # 현재 노드와 연결된 노드 탐색
            if not visited[next]:
                visited[next] = True
                queue.append(next)  # 큐에 데이터 삽입
                parent[next] = now_node  # 부모 노드 저장
                depth[next] = depth[now_node] + 1  # 노드 depth 저장

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

def LCA(a, b):
    if depth[a] < depth[b]: # a노드가 더 작으면 swap, 더 깊은 depth가 a가 되도록
        temp =a
        a=b
        b=temp
    while depth[a]!=depth[b]:  # depth 맞추기
        a=parent[a]
    while a!=b: # 공통조상찾기
        a=parent[a]
        b=parent[b]

    return a

m=int(input())
mydict = dict()
for _ in range(m):
    a, b = map(int, input().split())
    if not mydict.get((a, b), 0): #같은 질문일 경우 재계산을 하지 않기 위해 딕셔너리 자료형 사용
        mydict[(a, b)] = mydict[(b, a)] = LCA(a, b)
    print(mydict.get((a, b)))

 

 

 

 

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

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

karla.tistory.com

 

 

728x90
저작자표시 비영리 변경금지
'Coding Test/Tree' 카테고리의 다른 글
  • [14425] 문자열 집합 (트라이, Trie)
  • [10868] 최솟값 (세그먼트 트리)
  • [1068] 트리 (리프 노드의 개수 구하기, DFS)
  • [11725] 트리의 부모 찾기 (DFS)
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)
  • 블로그 메뉴

    • 홈
  • 링크

  • 공지사항

  • 인기 글

  • 태그

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

티스토리툴바