ps:problems:programmers:68937
                목차
트리 트리오 중간값
| ps | |
|---|---|
| 링크 | programmers.co.kr/… | 
| 출처 | 프로그래머스 | 
| 문제 번호 | 68937 | 
| 문제명 | 트리 트리오 중간값 | 
| 레벨 | Level 4 | 
| 분류 | 
 그래프, 트리  | 
	
| 시간복잡도 | O(n) | 
| 인풋사이즈 | n<=250,000 | 
| 사용한 언어 | Python | 
| 해결날짜 | 2021/01/16 | 
풀이
- 구하라고 하는 값이 설명으로는 좀 복잡해보이는데, 따져보면 단순하다.
 - 우선, 트리의 지름이란 트리에 존재하는 경로중 가장 긴 경로의 길이를 의미한다는 것을 기억하자.
 - v1과 v2 사이의 거리가 트리의 지름일 때 이 값을 d라고 하면,
- v1과 v3 사이의 거리 또는 v2과 v3 사이의 거리가 d인 v3가 존재하면, 답은 d이다.
- (v1, v2, v3)를 잡으면 되니까..
 
 - 그런 v3가 존재하지 않는다면 답은 d-1 이다
- 1) 이 경우, 중간값이 d인 세 점은 존재할 수 없다. 만약 다른 두 노드 v3, v4사이의 거리가 d라면, 즉 dist(v3,v4)=d라면, 역시 dist(v1,v3)=dist(v2,v3)=d 도 성립하게 되기 때문이다.
 - 2) 중간값이 d-1이 되는 세 점은 언제나 존재한다. v3를 v2의 이웃 노드로 잡으면 dist(v1,v2)=d, dist(v1,v3)=d-1, dist(v2,v3)=1 이니까 중간값은 d-1이 된다
 
 
 - 구현은 위 로직을 그대로 따르면 된다
- 1) 트리의 지름을 구하기 위해, 임의의 노드로부터 가장 먼 노드 v1을 구한다
 - 2) v1으로부터 거리가 가장 먼 노드 v2를 구한다.
 - 3) 거리가 가장 먼 노드가 2개 이상 존재하면 그 거리(=지름) d를 리턴
 - 4) v2으로부터 거리가 d인 노드가 2개 이상 존재하면 d를 리턴
 - 5) 다 해당 안되면 d-1을 리턴
 
 - 3번의 BFS로 해결 가능하다. 시간 복잡도는 3*O(n) = O(n)
 
코드
"""Solution code for "Programmers 68937. 트리 트리오 중간값".
- Problem link: https://programmers.co.kr/learn/courses/30/lessons/68937
- Solution link: http://www.teferi.net/ps/problems/programmers/68937
"""
import operator
from teflib import tgraph
def solution(n, edges):
    graph = [set() for _ in range(n)]
    for u, v in edges:
        graph[u - 1].add(v - 1)
        graph[v - 1].add(u - 1)
    dists = tgraph.min_distances(graph, 0)
    v1 = max(enumerate(dists), key=operator.itemgetter(1))[0]
    dists_from_v1 = tgraph.min_distances(graph, v1)
    diameter = max(dists_from_v1)
    v2 = [u for u, dist in enumerate(dists_from_v1) if dist == diameter]
    if len(v2) > 1 or tgraph.min_distances(graph, v2[0]).count(diameter) > 1:
        return diameter
    return diameter - 1
ps/problems/programmers/68937.txt · 마지막으로 수정됨: 2021/01/16 15:37 저자 teferi
                
                
토론