728x90
https://www.acmicpc.net/problem/11437
11437번: LCA
첫째 줄에 노드의 개수 N이 주어지고, 다음 N-1개 줄에는 트리 상에서 연결된 두 정점이 주어진다. 그 다음 줄에는 가장 가까운 공통 조상을 알고싶은 쌍의 개수 M이 주어지고, 다음 M개 줄에는 정
www.acmicpc.net
해당 문제는 특정 정점2개의 공통 조상을 찾는 문제입니다. 우선 각 정점을 깊이우선탐색으로 각각의 깊이를 구합니다.
구하려는 정점 2개의 공통조상을 찾기위하여 두 정점의 깊이를 맞춰주는데, 자기자신의 조상이 깊이우선탐색을 하면서 기록되었기 때문에 자기자신의 조상을 참조하면서 올라갑니다. 두 정점의 깊이가 일치할경우 같이 조상으로 올라가면서 같은 조상인지 판별 하면 됩니다. 해당문제는 O(n*m) 의시간복잡도를 갖습니다. 조상을 찾아가는 시간복잡도는 O(n)이고 쿼리의 개수가 주어지면 O(m) 이기 때문입니다.
import sys
sys.setrecursionlimit(int(1e5))
N = int(input()) # 노드의 개수
graph = [[] for _ in range(N+1)]
for _ in range(N-1):
a ,b = map(int, input().split())
graph[a].append(b)
graph[b].append(a)
M = int(input()) # 쌍의 개수
d = [0 for _ in range(N+1)]
c = [False for _ in range(N+1)]
parent = [0 for _ in range(N+1)]
def dfs(rootnode, depth):
d[rootnode] = depth
c[rootnode] = True
for childnode in graph[rootnode]:
if not c[childnode]:
parent[childnode] = rootnode
dfs(childnode, depth+1)
def lca(a,b):
# 노드의 깊이를 서로 맞춘다.
while d[a] != d[b]: # a가 b보다 깊이가 큰경우
if d[a] > d[b]:
a = parent[a] # a가 거슬러 올라간다.
else:
b = parent[b] # b가 거슬로 올라간다.
while a != b:
a = parent[a]
b = parent[b]
return a
dfs(1,0)
for i in range(M):
a, b = map(int, input().split())
print(lca(a,b))
728x90
'알고리즘 > 백준' 카테고리의 다른 글
[백준] 1016번 : 제곱 ㄴㄴ수 (0) | 2023.08.04 |
---|---|
[백준] 11438번 : LCA 2 (0) | 2023.08.03 |
[백준] 2263번 : 트리의 순회 (0) | 2023.08.01 |
[백준] 1197번 : 최소 스패닝 트리 (0) | 2023.07.31 |
[백준] 17472번 : 다리 만들기 2 (0) | 2023.07.31 |