結果
| 問題 |
No.898 tri-βutree
|
| コンテスト | |
| ユーザー |
|
| 提出日時 | 2022-02-23 22:45:57 |
| 言語 | PyPy3 (7.3.15) |
| 結果 |
AC
|
| 実行時間 | 1,958 ms / 4,000 ms |
| コード長 | 1,781 bytes |
| コンパイル時間 | 146 ms |
| コンパイル使用メモリ | 82,332 KB |
| 実行使用メモリ | 228,352 KB |
| 最終ジャッジ日時 | 2024-07-01 23:12:20 |
| 合計ジャッジ時間 | 32,590 ms |
|
ジャッジサーバーID (参考情報) |
judge5 / judge1 |
(要ログイン)
| ファイルパターン | 結果 |
|---|---|
| sample | AC * 1 |
| other | AC * 21 |
ソースコード
from collections import defaultdict, deque
import sys
sys.setrecursionlimit(10**6)
n = int(input())
max_log_v = 30
# 親を2^k回辿って到達する頂点(根を通り過ぎる場合は-1とする)
Parent = [[-1 for _ in range(n)] for _ in range(max_log_v)]
Depth = [-1 for _ in range(n)]
def dfs(curr, prev, d):
Parent[0][curr] = prev
Depth[curr] = d
for np, _ in edge[curr]:
if np == prev:
continue
dfs(np, curr, d + 1)
def init():
root = 0
# Parent[0]とDepthを根rootの木として初期化する
dfs(root, -1, 0)
# Parentを初期化する
for i in range(max_log_v - 1):
for v in range(n):
if Parent[i][v] < 0:
Parent[i + 1][v] = -1
else:
Parent[i + 1][v] = Parent[i][Parent[i][v]]
def check_LCA(u, v):
if Depth[u] > Depth[v]:
u, v = v, u
for i in range(max_log_v):
if (Depth[v] - Depth[u]) >> i & 1:
v = Parent[i][v]
if u == v:
return u
for i in range(max_log_v - 1, -1, -1):
if Parent[i][u] != Parent[i][v]:
u = Parent[i][u]
v = Parent[i][v]
return Parent[0][u]
edge = defaultdict(list)
for _ in range(n - 1):
u, v, w = map(int, input().split())
edge[u].append((v, w))
edge[v].append((u, w))
init()
INF = 1 << 60
D = [INF for _ in range(n)]
D[0] = 0
Que = deque([(0, 0)])
while Que:
curr, d = Que.popleft()
for np, w in edge[curr]:
if d + w > D[np]:
continue
D[np] = d + w
Que.append((np, d + w))
def dist(u, v):
return D[u] + D[v] - 2 * D[check_LCA(u, v)]
q = int(input())
for _ in range(q):
x, y, z = map(int, input().split())
print((dist(x, y) + dist(y, z) + dist(z, x)) // 2)