[백준] 사회망 서비스(SNS) (tree DP)

2025. 8. 17. 02:07·Algorithm/Coding Test Records

문제 소개

백준 2533번 사회망 서비스(SNS) 문제 정리합니다.

이 문제는 친구 관계가 트리로 주어졌을 때 최소 얼리 어답터 수를 구하는 문제입니다.

핵심은 각 노드의 상태(얼리 어답터 여부)에 따른 최적값을 DP로 계산하는 데 있습니다.

문제 링크: 사회망 서비스(SNS) - 백준 2533번


 

문제 접근 방식

이 문제는 다음과 같은 방식으로 접근했습니다:

  1. 문제 조건 분석: 얼리 어답터가 아닌 사람은 모든 친구가 얼리 어답터여야 함
  2. 그래프 특성 - 트리: 친구 관계가 트리 구조로 주어짐 (사이클 없음)
  3. 완전탐색의 한계: 각 사람마다 2가지 선택(얼리 어답터 O/X)이 있으므로 2^N은 시간초과
  4. 분할정복 아이디어: 부모 노드의 답 = 자식 노드들의 답을 조합해서 구할 수 있음
    • 부모가 얼리 어답터면: 자식은 어떤 상태든 OK → min(자식이 얼리 어답터 아닌 경우, 자식이 얼리 어답터인 경우) 선택
    • 부모가 얼리 어답터 아니면: 모든 자식이 얼리 어답터여야 함 → 자식이 얼리 어답터인 경우 강제 선택
  5. DP 상태 정의: dp[node][0/1] = node가 얼리 어답터 아닌(0)/인(1) 경우의 최적해
  6. 트리 DP 적용: 리프부터 시작해서 부모로 올라가며 최적값 전파

해결 과정 및 코드

핵심 아이디어

  1. DP 상태 정의: 각 노드에 대해 2가지 경우로 나누어 계산
    • dp[node][0]: node가 얼리 어답터가 아닌 경우의 최소값
    • dp[node][1]: node가 얼리 어답터인 경우의 최소값
  2. 점화식: 자식들의 DP 값을 이용해 부모 계산
    • dp[node][0] = sum(dp[child][1]) (모든 자식이 얼리 어답터)
    • dp[node][1] = 1 + sum(min(dp[child][0], dp[child][1])) (자식은 자유)
  3. DFS 순회: 리프 노드부터 계산하는 Post-order 방식 사용
  4. 임의 루트: 트리이므로 아무 노드나 루트로 설정해도 답은 동일

코드

시간 복잡도: O(N) - 각 노드를 한 번씩만 방문

공간 복잡도: O(N) - DP 테이블과 인접 리스트

import java.io.*;
import java.util.*;

public class Main {
    static ArrayList<Integer>[] adj; // 인접리스트 - 그래프(트리)
    static int[][] dp;
    static boolean[] visited;
    public static void main(String[] args) throws IOException {
        int n = read();
        // 인접 리스트 초기화
        adj = new ArrayList[n + 1];
        for (int i = 1; i <= n; i++) adj[i] = new ArrayList<>();
        // 간선 정보 입력 (무방향 그래프)
        for (int i = 0; i < n - 1; i++) {
            int u = read(), v = read();
            adj[u].add(v); adj[v].add(u);
        }

        // DP 테이블과 방문 배열 초기화
        dp = new int[n + 1][2];
        visited = new boolean[n + 1];
        // 1번 노드를 루트로 하여 DFS 실행
        dfs(1);
        // 루트가 얼리 어답터인 경우와 아닌 경우 중 최소값 출력
        System.out.println(Math.min(dp[1][0], dp[1][1]));
    }

    static void dfs(int node) {
        visited[node] = true;
        // 초기값 설정
        dp[node][0] = 0; // node가 얼리 어답터가 아닌 경우
        dp[node][1] = 1; // node가 얼리 어답터인 경우 (자기 자신 포함)

        // 모든 자식 노드에 대해 재귀적으로 계산
        for (int child : adj[node]) {
            if (visited[child]) continue; // 이미 방문한 노드 제외

            dfs(child); // 자식 노드 먼저 계산 (Post-order)

            // node가 얼리 어답터가 아니면, 모든 자식은 얼리 어답터여야 함
            dp[node][0] += dp[child][1];
            // node가 얼리 어답터이면, 자식은 얼리 어답터이거나 아니거나 상관없음
            dp[node][1] += Math.min(dp[child][0], dp[child][1]);
        }
    }

    // 빠른 입력을 위한 read 함수
    public static int read() throws IOException {
        int cur, n = System.in.read() & 15;
        boolean isNegative = (n == 13);
        if (isNegative) n = System.in.read() & 15;
        while ((cur = System.in.read()) > 32) n = (n << 3) + (n << 1) + (cur & 15);
        return isNegative ? -n : n;
    }
}

트리 DP 개념 정리

트리 DP란?
트리 구조에서 노드의 상태를 기반으로 동적 계획법을 적용하는 기법입니다.

트리 DP의 특징:

  • Post-order 순회: 자식부터 계산하여 부모로 전파
  • 상태 분할: 각 노드의 가능한 상태들을 나누어 최적값 계산
  • 무사이클: 트리 구조라 중복 계산 없이 DP 적용 가능

문제에서의 적용:

dp[node][0] = Σ dp[child][1]           // node가 얼리 어답터 아님
dp[node][1] = 1 + Σ min(dp[child][0], dp[child][1])  // node가 얼리 어답터

DFS를 사용하는 이유:

  • 자연스러운 Post-order: 재귀로 자식을 먼저 처리
  • 코드 간결성: 복잡한 위상정렬 구현 불필요
  • 메모리 효율: 추가 자료구조 없이 재귀 스택만 사용

'Algorithm > Coding Test Records' 카테고리의 다른 글

[백준] 철도 (스위핑(Line Sweep))  (2) 2025.08.24
[백준] 사회망 서비스(SNS) (tree DP) 최적화  (4) 2025.08.17
[백준] 수들의 합4 (누적합)  (2) 2025.08.10
[백준] 점프 (DP) 참고 정리  (1) 2025.07.17
[백준] 점프 (DP)  (0) 2025.07.17
'Algorithm/Coding Test Records' 카테고리의 다른 글
  • [백준] 철도 (스위핑(Line Sweep))
  • [백준] 사회망 서비스(SNS) (tree DP) 최적화
  • [백준] 수들의 합4 (누적합)
  • [백준] 점프 (DP) 참고 정리
Celion
Celion
오늘도 평소처럼 화이팅!
  • Celion
    Orion Log
    Celion
  • 전체
    오늘
    어제
    • 전체 글 (144)
      • Uncompiled Thoughts (8)
        • 네이버 부스트캠프 10기 (5)
      • CS 기초부터 한 걸음씩 (34)
      • Code Odyssey (22)
      • Algorithm (77)
        • Coding Test Records (63)
      • Git (3)
      • reference (0)
  • 블로그 메뉴

    • 태그
    • 방명록
  • 태그

    알고리즘고득점kit
    boostcamp
    java
    프로그래머스
    문법정리
    시뮬레이션
    Level2
    greedy
    백준
    코테
    Kotlin
    Level3
  • 최근 글

  • 인기 글

  • 최근 댓글

  • hELLO· Designed By정상우.v4.10.4
Celion
[백준] 사회망 서비스(SNS) (tree DP)
상단으로

티스토리툴바