문제 설명
문제 풀이
- dfs를 이용한 DP문제이다.
- DP 테이블을 아래와 같이 두고 Top-down 방식의 재귀를 사용한다.
- DP[i][j] : i노드를 j 마을로 지정했을 때 하위 트리에서의 점수 최대값
- 현재 노드를 우수마을로 지정했을 때는 다음 노드는 모두 비우수마을로 지정해야함
-> result = SUM( DP[next][0] )
- 현재 노드를 비우수마을로 지정했을 떄는 다음 노드는 둘 중 최대값으로 지정해야함
-> result = SUM ( MAX (DP[next][0], DP[next][1] ) )
소스 코드 (JAVA)
import java.io.*;
import java.util.*;
public class Main {
static int N;
static int[] arr;
static int[][] dp;
static List<Integer>[] map;
static int dfs(int cur, int parent, int col) {
if (dp[cur][col] != -1) return dp[cur][col];
int result = 0;
if (col == 1) {
result = arr[cur];
for (int next : map[cur]) {
if (next == parent) continue;
result += dfs(next, cur, 0);
}
}
else {
for (int next : map[cur]) {
if (next == parent) continue;
result += Math.max(dfs(next, cur, 0), dfs(next, cur, 1));
}
}
return dp[cur][col] = result;
}
static void solve() throws IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(System.out));
N = Integer.parseInt(br.readLine());
arr = new int[N+1];
dp = new int[N+1][2];
map = new ArrayList[N+1];
for (int i = 1; i <= N; i++)
map[i] = new ArrayList<>();
StringTokenizer st = new StringTokenizer(br.readLine());
for (int i = 1; i <= N; i++) {
arr[i] = Integer.parseInt(st.nextToken());
Arrays.fill(dp[i], -1);
}
for (int i = 0; i < N-1; i++) {
st = new StringTokenizer(br.readLine());
int a = Integer.parseInt(st.nextToken());
int b = Integer.parseInt(st.nextToken());
map[a].add(b);
map[b].add(a);
}
int result = Math.max(dfs(1, 0, 0), dfs(1, 0, 1));
bw.write(result + "\n");
bw.flush();
}
public static void main(String[] args) throws IOException {
solve();
}
}