結果
問題 | No.1976 Cut then Connect |
ユーザー |
![]() |
提出日時 | 2025-03-31 17:47:52 |
言語 | PyPy3 (7.3.15) |
結果 |
AC
|
実行時間 | 297 ms / 2,000 ms |
コード長 | 3,821 bytes |
コンパイル時間 | 188 ms |
コンパイル使用メモリ | 82,588 KB |
実行使用メモリ | 102,124 KB |
最終ジャッジ日時 | 2025-03-31 17:49:15 |
合計ジャッジ時間 | 6,586 ms |
ジャッジサーバーID (参考情報) |
judge4 / judge2 |
(要ログイン)
ファイルパターン | 結果 |
---|---|
sample | AC * 2 |
other | AC * 31 |
ソースコード
import sysfrom collections import dequedef main():sys.setrecursionlimit(1 << 25)N = int(sys.stdin.readline())adj = [[] for _ in range(N + 1)]for _ in range(N - 1):u, v = map(int, sys.stdin.readline().split())adj[u].append(v)adj[v].append(u)def find_farthest(start):visited = [-1] * (N + 1)q = deque([start])visited[start] = 0max_dist = 0far_node = startwhile q:u = q.popleft()for v in adj[u]:if visited[v] == -1:visited[v] = visited[u] + 1q.append(v)if visited[v] > max_dist:max_dist = visited[v]far_node = vreturn far_node, visiteds, _ = find_farthest(1)t, dist_s = find_farthest(s)s_new, dist_t = find_farthest(t)assert s_new == s # To confirm t is farthest from sparent = [0] * (N + 1)q = deque([s])parent[s] = -1while q:u = q.popleft()for v in adj[u]:if parent[v] == 0 and v != parent[u]:parent[v] = uq.append(v)if v == t:q = deque() # Break earlybreakpath = []u = twhile u != s:path.append(u)u = parent[u]path.append(s)path = path[::-1]D = len(path) - 1d = [0] * (D + 1)for i in range(D + 1):current = path[i]prev_node = path[i - 1] if i > 0 else Nonenext_node = path[i + 1] if i < D else Nonebranches = []for v in adj[current]:if v != prev_node and v != next_node:branches.append(v)if not branches:d[i] = 0continuevisited = {current}max_depth = 0q = deque()for b in branches:q.append((b, 1))visited.add(b)max_depth = max(max_depth, 1)while q:u_node, depth = q.popleft()for v in adj[u_node]:if v not in visited and v != current:visited.add(v)new_depth = depth + 1if new_depth > max_depth:max_depth = new_depthq.append((v, new_depth))d[i] = max_depthmax_left = [0] * (D + 1)max_left_sub = [0] * (D + 1)current_max = d[0] + 0current_max_sub = d[0] - 0max_left[0] = current_maxmax_left_sub[0] = current_max_subfor i in range(1, D + 1):current_max = max(current_max, d[i] + i)current_max_sub = max(current_max_sub, d[i] - i)max_left[i] = current_maxmax_left_sub[i] = current_max_submax_right = [0] * (D + 1)max_right_sub = [0] * (D + 1)current_max = d[D] + Dcurrent_max_sub = d[D] - Dmax_right[D] = current_maxmax_right_sub[D] = current_max_subfor i in range(D - 1, -1, -1):current_max = max(current_max, d[i] + i)current_max_sub = max(current_max_sub, d[i] - i)max_right[i] = current_maxmax_right_sub[i] = current_max_submin_candidate = float('inf')for i in range(D):len1 = isum1 = max_left[i] + max_left_sub[i]diam1 = max(len1, sum1)len2 = D - (i + 1)if i + 1 > D:sum2 = 0else:sum2 = max_right[i + 1] + max_right_sub[i + 1]diam2 = max(len2, sum2)radii1 = (diam1 + 1) // 2radii2 = (diam2 + 1) // 2candidate = max(diam1, diam2, radii1 + radii2 + 1)if candidate < min_candidate:min_candidate = candidateprint(min_candidate)if __name__ == '__main__':main()