結果
| 問題 |
No.1212 Second Path
|
| コンテスト | |
| ユーザー |
lam6er
|
| 提出日時 | 2025-04-16 16:46:32 |
| 言語 | PyPy3 (7.3.15) |
| 結果 |
TLE
|
| 実行時間 | - |
| コード長 | 3,845 bytes |
| コンパイル時間 | 683 ms |
| コンパイル使用メモリ | 82,388 KB |
| 実行使用メモリ | 487,992 KB |
| 最終ジャッジ日時 | 2025-04-16 16:49:14 |
| 合計ジャッジ時間 | 10,361 ms |
|
ジャッジサーバーID (参考情報) |
judge1 / judge3 |
(要ログイン)
| ファイルパターン | 結果 |
|---|---|
| sample | -- * 3 |
| other | TLE * 1 -- * 44 |
ソースコード
import sys
from math import log2, ceil
from collections import defaultdict, deque
sys.setrecursionlimit(1 << 25)
def main():
input = sys.stdin.read().split()
ptr = 0
N = int(input[ptr])
ptr +=1
edges = [[] for _ in range(N+1)] # 1-based
edge_set = defaultdict(set)
for _ in range(N-1):
u = int(input[ptr])
v = int(input[ptr+1])
w = int(input[ptr+2])
ptr +=3
edges[u].append((v, w))
edges[v].append((u, w))
edge_set[u].add((v, w))
edge_set[v].add((u, w))
LOG = ceil(log2(N)) if N >1 else 1
parent = [[-1]*(N+1) for _ in range(LOG)]
depth = [0]*(N+1)
tin = [0]*(N+1)
tout = [0]*(N+1)
time = 0
root = 1
stack = [(root, -1, False)]
adj = [[] for _ in range(N+1)]
for u in range(1, N+1):
for v, w in edges[u]:
if v != parent[0][u]:
adj[u].append((v, w))
parent[0][root] = -1
while stack:
u, p, visited = stack.pop()
if visited:
tout[u] = time
time +=1
continue
tin[u] = time
time +=1
parent[0][u] = p
stack.append((u, p, True))
for v, w in sorted(adj[u], key=lambda x: -x[0]):
if v != p:
depth[v] = depth[u] +1
stack.append((v, u, False))
for k in range(1, LOG):
for v in range(1, N+1):
if parent[k-1][v] != -1:
parent[k][v] = parent[k-1][parent[k-1][v]]
def lca(u, v):
if depth[u] < depth[v]:
u, v = v, u
for k in reversed(range(LOG)):
if depth[u] - (1<<k) >= depth[v]:
u = parent[k][u]
if u == v:
return u
for k in reversed(range(LOG)):
if parent[k][u] != -1 and parent[k][u] != parent[k][v]:
u = parent[k][u]
v = parent[k][v]
return parent[0][u]
def is_ancestor(u, v):
return tin[u] <= tin[v] and tout[u] >= tout[v]
def get_path_up(u, a):
path = []
while u != a:
path.append(u)
u = parent[0][u]
path.append(a)
return path
def get_path(u, v):
a = lca(u, v)
path_u = get_path_up(u, a)
path_v = get_path_up(v, a)
path_v.pop()
return path_u + path_v[::-1]
edge_info = []
edge_to_idx = dict()
original_edges = [dict() for _ in range(N+1)]
for u in range(1, N+1):
for v, w in edges[u]:
original_edges[u][v] = w
for u in range(1, N+1):
edges[u].sort(key=lambda x: x[1])
Q = int(input[ptr])
ptr +=1
for _ in range(Q):
x = int(input[ptr])
y = int(input[ptr+1])
ptr +=2
if x == y:
print(-1)
continue
a = lca(x, y)
path_nodes = []
u = x
while u != a:
path_nodes.append(u)
u = parent[0][u]
path_nodes.append(a)
tmp = []
u = y
while u != a:
tmp.append(u)
u = parent[0][u]
path_nodes += tmp[::-1]
S = 0
path_edges = set()
for i in range(len(path_nodes)-1):
u = path_nodes[i]
v = path_nodes[i+1]
w = original_edges[u][v]
S += w
path_edges.add((u, v))
path_edges.add((v, u))
min_candidate = float('inf')
for u in path_nodes:
for v, w in edges[u]:
if (u, v) not in path_edges and (v, u) not in path_edges:
if w < min_candidate:
min_candidate = w
break
if min_candidate != float('inf'):
print(S + 2 * min_candidate)
else:
print(-1)
if __name__ == "__main__":
main()
lam6er