강의로 돌아가기
Jzakka

문제 풀이 아이디어

DP[node][0] : 해당 노드에 불이 켜져있을 떄 node를 루트로 하는 서브트리에서 최소로 불이 켜진 개수
DP[node][1] : 해당 노드에 불이 꺼져있을 때 node를 루트로 하는 서브트리에서 촤소로 불이 켜진 개수

부모 노드가 불이 켜져있다면, 자식들은 불이 켜지든 말든 상관 없으므로 DP[부모][0] = min(DP[자식노드][0], DP[자식노드][1])들의 합 + 1이 되고
부모노드 불이 꺼져있으면 자식들은 반드시 불이 켜져있어야 하므로 DP[부모][1] = DP[자식노드][0] 의 합으로 정의할 수 있습니다.

루트는 아무거나 잡고 dfs 후위순회를 통해 구하면 됩니다.
자바의 경우 노드 수가 100000개라 스택오버플로우를 주의해야 합니다.

작성중인 코드―Solution.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
import java.util.*;
import java.util.stream.*;

import static java.lang.System.*;

class Solution {
    List<Integer>[] graph;
    public int solution(int n, int[][] lighthouse) {
        graph = IntStream.rangeClosed(0,n)
            .mapToObj(i->new ArrayList())
            .toArray(List[]::new);

        for(int[] edge:lighthouse){
            int s = edge[0];
            int e = edge[1];

            graph[s].add(e);
            graph[e].add(s);
        }

        boolean[] visited = new boolean[n + 1];
        int[][] res = new int[n+1][2];
        Deque<Integer> stk = new ArrayDeque();
        // 자식 방문 전 +, 자식 방문 후 -
        stk.offerLast(1);
        while(!stk.isEmpty()){
            int node = stk.pollLast();
            // out.printf("node=%d%n", node);
            if(node > 0){
                visited[node] = true;
                stk.offerLast(-node);
                for(int child:graph[node]){
                    if(!visited[child]){
                        stk.offerLast(child);
                    }
                }
            }else{ // 자식 방문 후
                node = -node;
                for(int child:graph[node]){
                    if(res[child][0] > 0){
                        res[node][0] += Math.min(res[child][0], res[child][1]); // node를 켰을 때
                        res[node][1] += res[child][0]; // node를 껐을 때
                    }
                }
                res[node][0]++;
            }
        }

        return Math.min(res[1][0], res[1][1]);
    }
}
0 개의 답변
답변 쓰기
이 입력폼은 마크다운 문법을 지원합니다. 마크다운 가이드 를 참고하세요.