# By Gemini import sys def solve(): # 再帰深度を深く設定 # N が大きい場合 (例: 2*10^5) に備える sys.setrecursionlimit(200010) # --- 入力処理 --- try: N = int(sys.stdin.readline()) W = list(map(int, sys.stdin.readline().split())) adj = [[] for _ in range(N)] edges = [] # 辺 (u, v) を (0-indexed) で保存 for _ in range(N - 1): A, B = map(int, sys.stdin.readline().split()) u, v = A - 1, B - 1 adj[u].append(v) adj[v].append(u) edges.append((u, v)) except EOFError: return except Exception as e: # print(f"Input Error: {e}", file=sys.stderr) return # N < 3 の場合、辺を2本選べないが、問題文の前提 (N-1本の木) から # N >= 3 と想定される。 if N < 3: print(0) return # --- 全頂点の重みの総和 --- total_sum = sum(W) # --- 根付き木 (頂点0を根) の情報を計算 (DFS) --- parent = [-1] * N # parent[v]: 頂点vの親 subtree_sum = [0] * N # subtree_sum[v]: vを根とする部分木の重み総和 in_time = [-1] * N # in_time[v]: DFSの行きがけ順 out_time = [-1] * N # out_time[v]: DFSの帰りがけ順 timer = [0] # DFSの時刻 (ミュータブルなリストとして渡す) def dfs(v, p): parent[v] = p in_time[v] = timer[0] timer[0] += 1 s = W[v] # 自身の重み for u in adj[v]: if u == p: continue dfs(u, v) s += subtree_sum[u] # 子の部分木の重みを加算 subtree_sum[v] = s out_time[v] = timer[0] timer[0] += 1 # 頂点0を根としてDFSを実行 dfs(0, -1) # --- 祖先判定関数 (O(1)) --- # u が v の祖先 (u == v も含む) かどうか def is_ancestor(u, v): return in_time[u] <= in_time[v] and out_time[v] <= out_time[u] # --- 各辺 (N-1本) に対応する「子ノード」を特定 --- # 辺 (u, p) を削除したとき、p側 (根側) と u側 (子側) に分かれる。 # u (子ノード) の subtree_sum[u] が切り出される部分木の重み和となる。 child_nodes = [] for u, v in edges: if parent[v] == u: # v が u の子 child_nodes.append(v) else: # u が v の子 child_nodes.append(u) # child_nodes には N-1 個の頂点インデックスが入る min_diff = float('inf') # --- 2本の辺 (i, j) を全探索 O(N^2) --- num_edges = N - 1 for i in range(num_edges): v1 = child_nodes[i] S_A = subtree_sum[v1] # 辺iの削除で切り出される部分木の重み和 for j in range(i + 1, num_edges): v2 = child_nodes[j] S_B = subtree_sum[v2] # 辺jの削除で切り出される部分木の重み和 sums = [] # 場合分け: # 1. v1 が v2 の祖先 (辺iが辺jより根に近い) if is_ancestor(v1, v2): S1 = S_B # v2の部分木 S2 = S_A - S_B # v1の部分木からv2の部分木を除いたもの S3 = total_sum - S_A # v1の親側 (全体からv1の部分木を除いたもの) sums = [S1, S2, S3] # 2. v2 が v1 の祖先 (辺jが辺iより根に近い) elif is_ancestor(v2, v1): S1 = S_A # v1の部分木 S2 = S_B - S_A # v2の部分木からv1の部分木を除いたもの S3 = total_sum - S_B # v2の親側 (全体からv2の部分木を除いたもの) sums = [S1, S2, S3] # 3. v1 と v2 が祖先-子孫関係にない (並列な部分木) else: S1 = S_A # v1の部分木 S2 = S_B # v2の部分木 S3 = total_sum - S_A - S_B # それ以外 (根を含む部分) sums = [S1, S2, S3] # (最大値 - 最小値) の最小値を更新 diff = max(sums) - min(sums) if diff < min_diff: min_diff = diff # --- 出力 --- print(min_diff) if __name__ == "__main__": solve()