https://www.acmicpc.net/problem/2533
2533번: 사회망 서비스(SNS)
첫 번째 줄에는 친구 관계 트리의 정점 개수 N이 주어진다. 단, 2 ≤ N ≤ 1,000,000이며, 각 정점은 1부터 N까지 일련번호로 표현된다. 두 번째 줄부터 N-1개의 줄에는 각 줄마다 친구 관계 트리의 에
www.acmicpc.net
문제
풀이
특정 노드 i 번째로 갔다고 가정을하자. 그럼 두 가지의 경우가 나뉘는데 , (얼리아답터를 EA)
1. i번째가 EA 일 경우 => i의 자식은 EA 이거나 아니다.
2. i번째가 EA 아닐 경우 => i의 자식은 반드시 EA 여야함.
문제는 EA의 최소값을 구하는것이 목표이므로 , EA의 최솟값을 나타내는 메모배열을
DP[노드의수][EA] 로 나타낼 수 있다. 따라서 , 점화식은 DFS 방식으로 탐색한다면
dp[i][0] += dp[next][1];
dp[i][1] += Math.min(dp[next][0], dp[next][1]);
으로 표현이 가능하다.
DFS 특성상 가장 깊은데부터 재귀호출이 끝나면 처음지점까지 올라오기때문에 Bottom-UP 방식.이런식으로 올라오면서 채우다보면 맨 처음 Root 노드의 결과 값을 채우게 되면 끝이난다.Root 노드가 ( EA 일때 , EA가 아닐때 ) 값 중 큰 값이 정답.
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
|
import java.util.*;
import java.io.*;
import java.util.stream.Collectors;
public class Main{
static ArrayList<Integer>[] list;
static int[][] dp;
public static void main(String[] args) throws IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
int N = Integer.parseInt(br.readLine());
list = new ArrayList[N + 1];
dp = new int[N+1][2];
for(int i=1;i<=N;i++)
list[i] = new ArrayList<Integer>();
for(int i=1;i<N;i++){
int[] e = Arrays.stream(br.readLine().split(" ")).mapToInt(Integer::parseInt).toArray();
list[e[0]].add(e[1]);
list[e[1]].add(e[0]);
}
dfs(0,1);
System.out.println(Math.min(dp[1][0],dp[1][1]));
}
public static void dfs(int parent,int x){
dp[x][0] = 0;
dp[x][1] = 1;
for (int node : list[x]) {
if(node == parent)
continue;
dfs(x,node);
dp[x][0] += dp[node][1];
dp[x][1] += Math.min(dp[node][0], dp[node][1]);
}
}
}
|
cs |
'알고리즘,PS > 백준' 카테고리의 다른 글
[BOJ] 백준 [19581] 두 번째 트리의 지름 JAVA (0) | 2021.10.04 |
---|---|
[BOJ] 백준 [5719] 거의 최단 경로 JAVA (0) | 2021.10.02 |
[BOJ] 백준 [9252] LCS 2 JAVA (0) | 2021.09.29 |
[BOJ] 백준 [1005] ACM Craft JAVA (0) | 2021.09.28 |
[BOJ] 백준 [14002] 가장 긴 증가하는 부분수열4 JAVA (0) | 2021.09.27 |