結果
| 問題 | No.898 tri-βutree |
| コンテスト | |
| ユーザー |
detteiuu
|
| 提出日時 | 2026-01-27 00:59:10 |
| 言語 | PyPy3 (7.3.17) |
| 結果 |
AC
|
| 実行時間 | 3,276 ms / 4,000 ms |
| コード長 | 3,294 bytes |
| 記録 | |
| コンパイル時間 | 306 ms |
| コンパイル使用メモリ | 82,584 KB |
| 実行使用メモリ | 149,980 KB |
| 最終ジャッジ日時 | 2026-01-27 01:00:06 |
| 合計ジャッジ時間 | 52,881 ms |
|
ジャッジサーバーID (参考情報) |
judge5 / judge1 |
(要ログイン)
| ファイルパターン | 結果 |
|---|---|
| sample | AC * 1 |
| other | AC * 21 |
ソースコード
from collections import deque
class LCA:
def __init__(self, G, root=0):
V = len(G)
self.bit_length = 1
while 1<<self.bit_length < V:
self.bit_length += 1
self.parent = [[-1]*V for _ in range(self.bit_length)]
self.depth = [-1]*V
self.d = [-1]*V
self.bfs(G, root)
for i in range(self.bit_length-1):
for j in range(V):
if self.parent[i][j] != -1:
self.parent[i+1][j] = self.parent[i][self.parent[i][j]]
def bfs(self, G, root):
self.depth[root] = 0
self.d[root] = 0
que = deque()
que.append(root)
while que:
n = que.popleft()
for v, w in G[n]:
if self.depth[v] == -1:
self.depth[v] = self.depth[n]+w
self.d[v] = self.d[n]+1
self.parent[0][v] = n
que.append(v)
def lca(self, a, b):
if self.d[a] < self.d[b]:
a, b = b, a
for i in range(self.bit_length):
if (self.d[a]-self.d[b]) & 1<<i:
a = self.parent[i][a]
if a == b:
return a
for i in reversed(range(self.bit_length)):
if self.parent[i][a] != self.parent[i][b]:
a = self.parent[i][a]
b = self.parent[i][b]
return self.parent[0][a]
def dist(self, a, b):
return self.depth[a]+self.depth[b]-self.depth[self.lca(a, b)]*2
def is_ancestor(self, u, v):
return self.lca(u, v) == u
def kth_ancestor(self, n, k):
for i in range(self.bit_length):
if 1<<i & k:
n = self.parent[i][n]
if n == -1:
break
return n
def jump(self, u, v):
if u == v:
return u
if self.lca(u, v) == u:
return self.kth_ancestor(v, self.dist(u, v)-1)
else:
return self.parent[0][u]
def jump_k(self, u, v, k):
d = self.dist(u, v)
if d <= k:
return v
lca = self.lca(u, v)
if k <= self.depth[u]-self.depth[lca]:
return self.kth_ancestor(u, k)
else:
return self.kth_ancestor(v, d-k)
def on_path(self, u, v, x):
return self.dist(u, x)+self.dist(x, v) == self.dist(u, v)
def create_path(self, u, v, x):
if self.on_path(u, v, x):
return u, v
if self.on_path(u, x, v):
return u, x
if self.on_path(v, x, u):
return v, x
return -1, -1
N = int(input())
G = [[] for _ in range(N)]
for _ in range(N-1):
u, v, w = map(int, input().split())
G[u].append((v, w))
G[v].append((u, w))
Q = int(input())
query = [list(map(int, input().split())) for _ in range(Q)]
lca = LCA(G)
for x, y, z in query:
ans = lca.dist(x, y)
l, r = lca.create_path(x, y, z)
if l != -1:
print(lca.dist(l, r))
continue
xy, xz, yz = lca.lca(x, y), lca.lca(x, z), lca.lca(y, z)
if lca.depth[xz] < lca.depth[xy]:
ans += lca.dist(xy, z)
elif lca.depth[xz] < lca.depth[yz]:
ans += lca.dist(yz, z)
else:
ans += lca.dist(xz, z)
print(ans)
detteiuu