Algorithm
[백준(파이썬/Python)] 1167_트리의 지름
kindof
2021. 7. 26. 21:07
https://www.acmicpc.net/problem/1167
1167번: 트리의 지름
트리가 입력으로 주어진다. 먼저 첫 번째 줄에서는 트리의 정점의 개수 V가 주어지고 (2 ≤ V ≤ 100,000)둘째 줄부터 V개의 줄에 걸쳐 간선의 정보가 다음과 같이 주어진다. 정점 번호는 1부터 V까지
www.acmicpc.net
- 트리의 지름을 구하는 방법에 대한 약간의 사전지식(?)이 있어야 쉽게 풀 수 있는 문제입니다.
- 트리의 지름을 구하는 공식은 아래 주석에서 설명한 것처럼 크게 세 단계를 거칩니다.
1. 트리에서 임의의 정점 x를 찾는다.
2. 정점 x에서 가장 먼 정점 y를 찾는다.
3. 정점 y에서 가장 먼 정점 z를 찾는다.
--> 트리의 지름은 정점 y와 정점 z를 연결하는 경로다.
이에 대한 자세한 증명 과정은 아래 블로그를 참고했습니다.
트리의 지름 구하기
트리에서 지름이란, 가장 먼 두 정점 사이의 거리 혹은 가장 먼 두 정점을 연결하는 경로를 의미한다. 선형 시간안에 트리에서 지름을 구하는 방법은 다음과 같다: 1. 트리에서 임의의 정점 $x$를
blog.myungwoo.kr
따라서 이 문제는 모든 정점에 대하여 BFS를 수행하는 방식으로는 문제의 시간복잡도 제한을 맞출 수 없기 때문에 위에서 설명한 트리의 지름을 구하는 방식으로 단 두 번의 BFS를 통해 트리의 지름을 구해야 합니다.
최종적인 코드는 아래와 같습니다.
[풀이]
from collections import defaultdict, deque
import sys
# bfs로 끝 정점까지 거리 구하기
def getDistance(start):
randomNode, maxDistance = 0, 0
visited = [False] * (v+1)
visited[start] = True
q = deque()
q.append((start, 0))
while q:
currNode, distance = q.popleft()
if maxDistance < distance:
maxDistance = distance
randomNode = currNode
for childNode, dist in tree[currNode]:
if not visited[childNode]:
visited[childNode] = True
q.append((childNode, distance + dist))
return randomNode, maxDistance
v = int(input())
# 트리 정보 입력받기
tree = defaultdict(list)
for _ in range(v):
line = list(map(int, sys.stdin.readline().split()))
parent = line[0]
for i in range(1, len(line)-1, 2):
child, dist = line[i], line[i+1]
tree[parent].append((child, dist))
# 트리의 지름 구하기
# 1. 트리에서 임의의 정점 x를 찾는다.
# 2. 정점 x에서 가장 먼 정점 y를 찾는다.
# 3. 정점 y에서 가장 먼 정점 z를 찾는다.
randomNode, maxDistance = getDistance(1)
randomNode, maxDistance = getDistance(randomNode)
print(maxDistance)