-
Notifications
You must be signed in to change notification settings - Fork 5
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
18-jung0115 #177
18-jung0115 #177
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
문제에서 직원들의 직속 상사 관계가 트리구조라고 명시되어 있고 모든 직원이 소식을 듣는데 걸리는 시간의 최솟값을 구하라고 했으므로 DFS를 이용해서 풀면 되겠다고 생각했습니다. 그래서
- DFS로 트리를 탐색하면서 현재 노드의 자식 노드들로부터 통화하는데 걸리는 시간을 리스트에 저장합니다.
- 이 리스트를 내림차순으로 정렬하여 탐색이 오래 걸리는 자식부터 전화를 걸어, 각각의 통화 시간에 (1, 2, 3,...)을 곱해 더해줍니다.
- 이 중 현재 노드를 루트로 하는 트리의 통화 완료 시간인 최솟값을 구해주면 됩니다.
이런 로직을 바탕으로 접근해보았습니다!
import sys
input = sys.stdin.readline
n = int(input())
employees = list(map(int, input().split()))
# 각 직원의 자식들을 저장할 트리 리스트를 선언함
graph = [[] for _ in range(n)]
# 트리를 구축함
for i in range(1, n):
graph[employees[i]].append(i)
def dfs(cur):
# 자식 노드들의 통화 시간을 저장할 리스트를 선언함
childs = []
# 현재 노드의 자식들을 DFS로 탐색하며 통화 시간을 수집함
for next_employee in graph[cur]:
childs.append(dfs(next_employee))
# 자식 트리들의 통화 시간을 내림차순으로 정렬함
childs.sort(reverse=True)
# 순서대로 통화 시간을 더해줌
for i in range(len(childs)):
childs[i] += i + 1
# 자식이 없는 경우 0, 그렇지 않으면 최대 통화 시간을 리턴함
return max(childs, default=0)
# 루트 노드부터 DFS 탐색 시작 (0번 직원이 루트)
answer = dfs(0)
print(answer)
처음에 DFS라고는 생각했지만, 하위 트리들로부터 통화 시간을 역으로 계산하는 것과 동시에 전화를 걸 수 없다는 제약을 고려하여 통화 시간을 계산하는 아이디어를 떠오르기가 정말 쉽지 않았습니다...😭 덕분에 정미님의 수도 코드를 참고하면서 하나하나 코드를 생각하면서 구현해보니 로직을 이해할 수 있었습니다!
다음 PR도 팟팅입니닷😝
➡️ 풀이 코드
🔗 문제 링크
백준 | 다이나믹 프로그래밍 - 뉴스 전하기(1135)
✔️ 소요된 시간
1시간
✨ 수도 코드
직원들의 직속 상사 관계를 트리로 표현할 수 있는데, 이걸 2차원 배열에 정리해서 사용했습니다
예를 들어 1번 사원의 직속 상사가 2번이라면 2번 인덱스의 list에 1을 추가합니다. 이런식으로 상사/부하 관계를 정리하고
dfs + dp를 이용해서 시간의 최솟값을 구해줬습니다.
사실 dp를 사용하지 않아도 N(직원 수)의 최대가 50이라서 시간 초과는 나지 않지만 성능을 최적화하기 위해 dp까지 사용해봤습니다!
1명이 뉴스를 전파하는 데 걸리는 시간이 1분이고, 각 직원은 한 번에 한 명에게 전화를 할 수 있기 때문에
재귀로 최대 깊이를 계산해서 각 노드가 자신의 자식들에게 뉴스를 전파하는 순서를 결정하면 시간 계산이 가능합니다!
해당 직원의 모든 부하들에게 뉴스를 전하는 데 걸리는 시간을 계산해서 새로운 리스트를 만들고, 그 값을 내림차순으로 정렬해줬습니다.
가장 오래 걸리는 부하를 우선 처리해야, 정확한 시간을 구해줄 수 있기 때문에 정렬해줬습니다!
그리고 직원의 각 자식, 즉 직속 부하에게 전화를 거는 시간을 계산해줍니다.
이 중 가장 큰 값을 찾아서 dp에 저장해주고 이 과정을 반복하면 오민식부터 출발해서 모든 직원이 뉴스를 전달 받는 시간을 구해낼 수 있습니다!
✅ 최종 코드
📚 새롭게 알게된 내용