import sys
input = sys.stdin.readline
sys.setrecursionlimit(500000)
def root_dfs(node):
if visited[node]:
return
visited[node] = True
child_list = []
for next_node in tree[node]:
if not visited[next_node]:
child_list.append(next_node)
if len(child_list)==2:
return [node,0]
elif len(child_list) == 1:
return_value = root_dfs(child_list[0])
return_value[1] += tree[node][child_list[0]]
return return_value
else:
return [node,0]
def leef_dfs(node):
if visited[node]:
return
visited[node] = True
child_list = []
for next_node in tree[node]:
if not visited[next_node]:
child_list.append(next_node)
if len(child_list)==0:
return 0
else:
result = 0
for child_node in child_list:
result = max(result,leef_dfs(child_node)+tree[node][child_node])
return result
N,R = map(int,input().split())
tree = [{} for _ in range(N+1)]
for _ in range(N-1):
x,y,b = map(int,input().split())
tree[x][y] = b
tree[y][x] = b
visited = [False for _ in range(N+1)]
root_node_info = root_dfs(R)
visited[root_node_info[0]] = False
leef_dis = leef_dfs(root_node_info[0])
print(root_node_info[1],leef_dis)
2개의 DFS로 나눠서 최초엔 풀었다.
첫번째 풀이는 두개로 나뉘어서 DFS를 했다.
첫 DFS는 기가노드를 찾는것이다. 기가노드를 찾으면 그때의 길이를 저장해놓는다.
그리고 기가노드에서 부터 리프노드까지 최대 길이를 찾아내는 방식으로 해서 구했다.
import sys
input = sys.stdin.readline
sys.setrecursionlimit(300000)
def root_dfs(node,dis):
if visited[node]:
return
visited[node] = True
count = 0
nexts = -1
distance = 0
for next_node in tree[node]:
if not visited[next_node]:
count += 1
nexts = next_node
distance += tree[node][next_node]
if count == 1:
return root_dfs(nexts,dis+distance)
else:
return [node,dis]
def leaf_dfs(node,dis):
global leef_dis
visited[node] = True
count = 0
for next_node in tree[node]:
if not visited[next_node]:
leaf_dfs(next_node,dis+tree[node][next_node])
count += 1
if not count:
leef_dis = max(leef_dis,dis)
N,R = map(int,input().split())
tree = [{} for _ in range(N+1)]
for _ in range(N-1):
x,y,b = map(int,input().split())
tree[x][y] = b
tree[y][x] = b
visited = [False for _ in range(N+1)]
root_dis = root_dfs(R,0)
leef_dis = 0
leaf_dfs(root_dis[0],0)
print(root_dis[1],leef_dis)
두번째 풀이는 좀더 깔끔한 풀이이다.
count를 별도로 세주어서 기가노드인지 리프노드인지 구분을 해주었다.
기가노드가 아닐때에는 재귀를 해주면서 distance를 더해주고, 만약 기가노드일때는 재귀를 머추고, 기가노드의 위치와
지금까지 누적된 거리를 반환해준다.
leaf_dfs도 비슷한 과정을 겪는다.
leaf_dfs를 계속 재귀를 통해 가면서 leaf_node에 도착하면 현재까지 누적된 값과 최대값과 비교를 해서 더 큰 값을 넣어주면 된다.
'알고리즘 > 백준' 카테고리의 다른 글
[BOJ/백준] 21918 전구 (0) | 2021.06.10 |
---|---|
[BOJ/백준] 17470 배열 돌리기 5 (0) | 2021.06.10 |
[BOJ/백준] 20300 서강근육맨 (0) | 2021.06.07 |
[BOJ/백준] 19581 두번째 트리의 지름 (0) | 2021.06.07 |
[BOJ/백준] 15644 구슬 탈출 3 (0) | 2021.06.07 |