結果

問題 No.898 tri-βutree
ユーザー AEnAEn
提出日時 2022-11-23 22:41:07
言語 PyPy3
(7.3.15)
結果
AC  
実行時間 1,166 ms / 4,000 ms
コード長 2,224 bytes
コンパイル時間 381 ms
コンパイル使用メモリ 82,248 KB
実行使用メモリ 198,400 KB
最終ジャッジ日時 2024-09-25 02:41:50
合計ジャッジ時間 20,633 ms
ジャッジサーバーID
(参考情報)
judge4 / judge3
このコードへのチャレンジ
(要ログイン)

テストケース

テストケース表示
入力 結果 実行時間
実行使用メモリ
testcase_00 AC 789 ms
198,400 KB
testcase_01 AC 37 ms
52,736 KB
testcase_02 AC 41 ms
54,144 KB
testcase_03 AC 38 ms
54,400 KB
testcase_04 AC 40 ms
54,144 KB
testcase_05 AC 39 ms
54,656 KB
testcase_06 AC 39 ms
54,400 KB
testcase_07 AC 1,041 ms
101,760 KB
testcase_08 AC 1,049 ms
101,484 KB
testcase_09 AC 1,035 ms
101,664 KB
testcase_10 AC 1,033 ms
101,760 KB
testcase_11 AC 1,010 ms
101,888 KB
testcase_12 AC 1,166 ms
101,876 KB
testcase_13 AC 1,023 ms
101,720 KB
testcase_14 AC 1,022 ms
101,368 KB
testcase_15 AC 1,060 ms
101,760 KB
testcase_16 AC 1,078 ms
101,888 KB
testcase_17 AC 1,080 ms
101,504 KB
testcase_18 AC 1,061 ms
100,740 KB
testcase_19 AC 1,031 ms
101,248 KB
testcase_20 AC 1,090 ms
101,504 KB
testcase_21 AC 1,089 ms
101,796 KB
権限があれば一括ダウンロードができます

ソースコード

diff #

import sys
sys.setrecursionlimit(10**8)
import pypyjit
pypyjit.set_param("max_unroll_recursion=-1")

class LCA:
    """
    前処理O(nlogn)、クエリO(logn)
    木上の任意の2点のLCAを求める
    """
    def __init__(self, N, G, root = 0) -> None:
        """頂点数:N、辺情報:G、根のidx:root dabulingで前処理を行う"""
        self.G = G
        self.depth = [-1]*N
        self.dist = [-1]*N
        self.ancestors = [[-1]*(N+1)]
        self.depth[root] = 0
        self.dist[root] = 0
        self.dfs(root,-1)
        max_d = max([self.depth[i] for i in range(N)])

        d = 1
        prev = self.ancestors[0]
        while d<max_d:
            nex = [prev[i] for i in prev]
            self.ancestors.append(nex)
            d <<= 1
            prev = nex

    def dfs(self,v,p):
        for nex, cost in self.G[v]:
            if nex==p:continue
            self.depth[nex] = self.depth[v]+1
            self.dist[nex] = self.dist[v]+cost
            self.ancestors[0][nex] = v
            self.dfs(nex,v)
    
    def lca_query(self, u, v):
        """u,vの最小共通祖先を求める"""
        du, dv = self.depth[u], self.depth[v]
        if du>dv:
            u, v = v, u
            du, dv = dv, du
        # vを同じ高さまで上げる
        diff, idx = dv-du, 0
        while diff:
            if diff&1:
                v = self.ancestors[idx][v]
            diff >>= 1
            idx += 1
        if u==v:
            return u
        for i in range(len(bin(du)[2:])-1,-1,-1):
            pu, pv = self.ancestors[i][u], self.ancestors[i][v]
            if pu!=pv:
                u, v = pu, pv
        assert self.ancestors[0][u]==self.ancestors[0][v]
        return self.ancestors[0][u]
    
    def dist_query(self, u, v):
        lca = self.lca_query(u, v)
        return self.dist[u]+self.dist[v]-2*self.dist[lca]

N = int(input())
G = [list() for _ in range(N)]
for i in range(N-1):
    u, v, w = map(int, input().split())
    G[u].append((v,w))
    G[v].append((u,w))

lca = LCA(N,G)
Q = int(input())
for i in range(Q):
    x, y, z = map(int, input().split())
    res = [lca.dist_query(x, y), lca.dist_query(y,z), lca.dist_query(z,x)]
    print(sum(res)//2)
0