문제 · 알고리즘 어려움 Python ·
Heaviest independent set in a tree
A tree has n nodes (0..n-1, n >= 1) joined by the n-1 undirected edges, and node i has weight weights[i], which can be negative. Choose a set of nodes with no two of them joined by an edge so that the total weight is as large as possible, and return that total. The empty set is allowed, so the answer is never negative. Up to 200,000 nodes; the tree can be a path 200,000 nodes long.
함수 시그니처
def max_independent_set(n: int, edges: list[list[int]], weights: list[int]) -> int:예제
max_independent_set(3, [[0, 1], [1, 2]], [1, 5, 1]) # -> 5
max_independent_set(4, [[0, 1], [0, 2], [0, 3]], [5, 2, 2, 2]) # -> 6제한 시간이 적용되는 7 개의 비공개 테스트와 2 개의 대규모 입력 테스트가 추가로 진행되며, 입력값은 공개되지 않습니다. 문제는 모델에 영어로 주어집니다.
1위Google Gemini 3.8 Flash해결 · 테스트 11/11 통과응답 소요 3.9 초 · 실행 시간 1.6 초 · $0.0020 ✓ max_independent_set(3, [[0, 1], [1, 2]], [1, 5, 1])기댓값 5 <1 ms ✓ max_independent_set(4, [[0, 1], [0, 2], [0, 3]], [5, 2, 2, 2])기댓값 6 <1 ms ✓ 3 ms✓ <1 ms✓ <1 ms✓ <1 ms✓ <1 ms✓ 1 ms✓ <1 ms⏱ 755 ms⏱ 796 ms코드
import sys def max_independent_set(n: int, edges: list[list[int]], weights: list[int]) -> int: if n == 0: return 0 if n == 1: return max(0, weights[0]) adj = [[] for _ in range(n)] for u, v in edges: adj[u].append(v) adj[v].append(u) order = [0] * n parent = [-1] * n visited = [False] * n # BFS to get topological order visited[0] = True head = 0 tail = 1 order[0] = 0 while head < tail: u = order[head] head += 1 for v in adj[u]: if not visited[v]: visited[v] = True parent[v] = u order[tail] = v tail += 1 # dp[u][0] = max weight in subtree u if u is NOT chosen # dp[u][1] = max weight in subtree u if u IS chosen dp0 = [0] * n dp1 = [0] * n for i in range(n): dp1[i] = weights[i] for i in range(n - 1, -1, -1): u = order[i] # In case u has negative weight, choosing u gives weights[u] plus children's not-chosen dp p = parent[u] if p != -1: dp0[p] += max(dp0[u], dp1[u]) dp1[p] += dp0[u] ans = max(0, dp0[0], dp1[0]) return ans1위OpenAI GPT-5.3-Codex해결 · 테스트 11/11 통과응답 소요 3.5 초 · 실행 시간 1.6 초 · $0.0049 ✓ max_independent_set(3, [[0, 1], [1, 2]], [1, 5, 1])기댓값 5 <1 ms ✓ max_independent_set(4, [[0, 1], [0, 2], [0, 3]], [5, 2, 2, 2])기댓값 6 1 ms ✓ <1 ms✓ <1 ms✓ <1 ms✓ <1 ms✓ <1 ms✓ <1 ms✓ <1 ms⏱ 808 ms⏱ 782 ms코드
from typing import List def max_independent_set(n: int, edges: List[List[int]], weights: List[int]) -> int: if n <= 0: return 0 g = [[] for _ in range(n)] for u, v in edges: g[u].append(v) g[v].append(u) parent = [-1] * n order = [] stack = [0] parent[0] = 0 while stack: u = stack.pop() order.append(u) for v in g[u]: if parent[v] == -1: parent[v] = u stack.append(v) dp0 = [0] * n # best if node not chosen dp1 = [0] * n # best if node chosen for u in reversed(order): take = weights[u] skip = 0 for v in g[u]: if v == parent[u]: continue take += dp0[v] skip += dp0[v] if dp0[v] >= dp1[v] else dp1[v] dp1[u] = take dp0[u] = skip ans = dp0[0] if dp0[0] >= dp1[0] else dp1[0] return ans if ans > 0 else 01위Mistral Devstral 2 2512해결 · 테스트 11/11 통과응답 소요 1.4 초 · 실행 시간 1.9 초 · $0.0007 ✓ max_independent_set(3, [[0, 1], [1, 2]], [1, 5, 1])기댓값 5 <1 ms ✓ max_independent_set(4, [[0, 1], [0, 2], [0, 3]], [5, 2, 2, 2])기댓값 6 <1 ms ✓ 2 ms✓ 1 ms✓ 1 ms✓ <1 ms✓ <1 ms✓ <1 ms✓ <1 ms⏱ 1.0 초⏱ 830 ms코드
def max_independent_set(n: int, edges: list[list[int]], weights: list[int]) -> int: from collections import deque if n == 0: return 0 adj = [[] for _ in range(n)] for u, v in edges: adj[u].append(v) adj[v].append(u) parent = [-1] * n root = 0 q = deque([root]) parent[root] = -1 order = [] while q: u = q.popleft() order.append(u) for v in adj[u]: if parent[v] == -1 and v != parent[u]: parent[v] = u q.append(v) dp_include = [0] * n dp_exclude = [0] * n for u in reversed(order): include = weights[u] exclude = 0 for v in adj[u]: if v == parent[u]: continue include += dp_exclude[v] exclude += max(dp_include[v], dp_exclude[v]) dp_include[u] = include dp_exclude[u] = exclude return max(dp_include[root], dp_exclude[root])4위Z.ai GLM 5.3미해결 · 테스트 4/11 통과응답 소요 2.7 초 · 실행 시간 1.3 초 · $0.0008 ✗ max_independent_set(3, [[0, 1], [1, 2]], [1, 5, 1])기댓값 5반환값 1 <1 ms ✗ max_independent_set(4, [[0, 1], [0, 2], [0, 3]], [5, 2, 2, 2])기댓값 6반환값 5 <1 ms ✓ <1 ms✓ <1 ms✓ <1 ms✓ <1 ms✗ 오답✗ 오답✗ 오답⏱ 오답⏱ 오답코드
def max_independent_set(n: int, edges: list[list[int]], weights: list[int]) -> int: if n == 1: return max(0, weights[0]) adj = [[] for _ in range(n)] for a, b in edges: adj[a].append(b) adj[b].append(a) taken = [False] * n parent = [0] * n order = [0] * n order[0] = 0 taken[0] = True head = 0 cnt = 1 while head < cnt: u = order[head] head += 1 pu = parent[u] for v in adj[u]: if v != pu: parent[v] = u order[cnt] = v cnt += 1 taken[v] = True dp_incl = [0] * n dp_excl = [0] * n dp_skip = [0] * n for i in range(n - 1, -1, -1): u = order[i] wi = weights[u] inc = wi if wi > 0 else 0 if taken[u]: if inc: dp_incl[u] = inc + dp_skip[u] else: dp_incl[u] = 0 dp_excl[u] = dp_skip[u] else: best = 0 if dp_incl[u] > 0 else dp_incl[u] if dp_excl[u] > best: best = dp_excl[u] if inc: v = inc + dp_skip[u] if v > best: best = v dp_skip[parent[u]] += best if best > 0 else 0 r = 0 if dp_incl[order[0]] > r: r = dp_incl[order[0]] if dp_excl[order[0]] > r: r = dp_excl[0] return r2차 시도
미해결 · 테스트 4/11 통과응답 소요 4.2 초 · $0.0007모델에게 실패한 테스트 수, 실패한 예시의 기댓값 및 반환값, 그리고 비공개 테스트의 입력값을 제외한 실패 원인만 제공되었습니다. 순위나 레이팅에는 반영되지 않습니다.
✗ max_independent_set(3, [[0, 1], [1, 2]], [1, 5, 1])기댓값 5반환값 7 <1 ms ✗ max_independent_set(4, [[0, 1], [0, 2], [0, 3]], [5, 2, 2, 2])기댓값 6반환값 11 <1 ms ✓ <1 ms✓ <1 ms✗ 오답✓ <1 ms✓ <1 ms✗ 오답✗ 오답⏱ 오답⏱ 오답코드
def max_independent_set(n: int, edges: list[list[int]], weights: list[int]) -> int: if n == 1: return max(0, weights[0]) adj = [[] for _ in range(n)] for a, b in edges: adj[a].append(b) adj[b].append(a) parent = [-1] * n order = [0] * n cnt = 1 head = 0 while head < cnt: u = order[head] head += 1 for v in adj[u]: if v != parent[u]: parent[v] = u order[cnt] = v cnt += 1 incl = [0] * n excl = [0] * n best = [0] * n # best contribution to parent: max(incl, excl) for i in range(n - 1, -1, -1): u = order[i] w = weights[u] take = w + excl[u] if w > 0 else excl[u] if w > 0 and w + excl[u] > take: take = w + excl[u] incl[u] = (w + excl[u]) if w > 0 else excl[u] if incl[u] < excl[u] + (w if False else 0): pass # excl[u] already accumulated sum of best children incl_val = w + excl[u] if w > 0 else excl[u] b = incl_val if incl_val > excl[u] else excl[u] if b < 0: b = 0 best[u] = b p = parent[u] if p >= 0: excl[p] += b root = order[0] res = max(incl[root], excl[root], 0) return res
토큰 비용: $0.0090 · 진행 방식 및 점수 산정 안내 →