結果

問題 No.898 tri-βutree
ユーザー Coki628Coki628
提出日時 2020-08-07 18:23:26
言語 PyPy3
(7.3.15)
結果
AC  
実行時間 904 ms / 4,000 ms
コード長 2,554 bytes
コンパイル時間 393 ms
コンパイル使用メモリ 82,560 KB
実行使用メモリ 113,408 KB
最終ジャッジ日時 2024-11-08 23:48:31
合計ジャッジ時間 16,405 ms
ジャッジサーバーID
(参考情報)
judge5 / judge1
このコードへのチャレンジ
(要ログイン)

テストケース

テストケース表示
入力 結果 実行時間
実行使用メモリ
testcase_00 AC 342 ms
112,256 KB
testcase_01 AC 43 ms
52,864 KB
testcase_02 AC 54 ms
60,928 KB
testcase_03 AC 53 ms
60,672 KB
testcase_04 AC 53 ms
60,544 KB
testcase_05 AC 53 ms
60,672 KB
testcase_06 AC 53 ms
60,672 KB
testcase_07 AC 839 ms
112,768 KB
testcase_08 AC 848 ms
113,152 KB
testcase_09 AC 858 ms
112,768 KB
testcase_10 AC 851 ms
112,768 KB
testcase_11 AC 862 ms
112,896 KB
testcase_12 AC 904 ms
112,768 KB
testcase_13 AC 874 ms
112,640 KB
testcase_14 AC 889 ms
112,768 KB
testcase_15 AC 848 ms
113,408 KB
testcase_16 AC 858 ms
112,640 KB
testcase_17 AC 858 ms
112,896 KB
testcase_18 AC 863 ms
112,896 KB
testcase_19 AC 857 ms
113,408 KB
testcase_20 AC 852 ms
113,024 KB
testcase_21 AC 865 ms
113,024 KB
権限があれば一括ダウンロードができます

ソースコード

diff #

import sys

def input(): return sys.stdin.readline().strip()
def list2d(a, b, c): return [[c] * b for i in range(a)]
def list3d(a, b, c, d): return [[[d] * c for j in range(b)] for i in range(a)]
def list4d(a, b, c, d, e): return [[[[e] * d for j in range(c)] for j in range(b)] for i in range(a)]
def ceil(x, y=1): return int(-(-x // y))
def INT(): return int(input())
def MAP(): return map(int, input().split())
def LIST(N=None): return list(MAP()) if N is None else [INT() for i in range(N)]
def Yes(): print('Yes')
def No(): print('No')
def YES(): print('YES')
def NO(): print('NO')
sys.setrecursionlimit(10 ** 9)
INF = 10 ** 19
MOD = 10 ** 9 + 7
EPS = 10 ** -10

class LCA:
    """ LCA(最小共通祖先) """

    def __init__(self, nodes, root):
        self.N = len(nodes)
        nv = 1
        MAX = 0
        while nv < self.N:
            nv *= 2
            MAX += 1
        self.MAX = MAX
        self.nxt = list2d(MAX, self.N, -1)
        self.depths, self.cost = self.dfs(self.N, nodes, root)
        for k in range(1, MAX):
            for v in range(self.N):
                if self.nxt[k-1][v] == -1: 
                    continue
                self.nxt[k][v] = self.nxt[k-1][self.nxt[k-1][v]]

    def dfs(self, N, nodes, src):
        stack = [(src, -1, 0, 0)]
        depths = [INF] * N
        cost = [INF] * N
        while stack:
            u, prev, d, c = stack.pop()
            depths[u] = d
            cost[u] = c
            self.nxt[0][u] = prev
            for v, nxc in nodes[u]:
                if v != prev:
                    stack.append((v, u, d+1, c+nxc))
        return depths, cost

    def get_lca(self, a, b):
        if self.depths[a] > self.depths[b]:
            a, b = b, a
        gap = self.depths[b] - self.depths[a]
        for i in range(self.MAX):
            if gap & 1<<i:
                b = self.nxt[i][b]
        if a == b:
            return a
        else:
            for i in range(self.MAX-1, -1, -1):
                a2 = self.nxt[i][a]
                b2 = self.nxt[i][b]
                if a2 != b2:
                    a = a2
                    b = b2
            return self.nxt[0][a]

N = INT()
nodes = [[] for i in range(N)]
for i in range(N-1):
    a, b, c = MAP()
    nodes[a].append((b, c))
    nodes[b].append((a, c))

lca = LCA(nodes, 0)

Q = INT()
for _ in range(Q):
    xyz = LIST()

    ans = 0
    for i in range(3):
        a, b = xyz[i], xyz[(i+1)%3]
        l = lca.get_lca(a, b)
        ans += lca.cost[a] + lca.cost[b] - lca.cost[l]*2
    ans //= 2
    print(ans)
0