알고리즘 문제 풀이/BOJ 골드
[백준] 2533 - 사회망 서비스 (SNS)
natonato
2022. 2. 27. 19:23
2533번: 사회망 서비스(SNS)
첫 번째 줄에는 친구 관계 트리의 정점 개수 N이 주어진다. 단, 2 ≤ N ≤ 1,000,000이며, 각 정점은 1부터 N까지 일련번호로 표현된다. 두 번째 줄부터 N-1개의 줄에는 각 줄마다 친구 관계 트리의 에
www.acmicpc.net
0. 모든 친구가 얼리-어답터라면 자신도 어답터가 된다
- 얼리-어답터가 아닌 두 사람이 친구라면, 이 둘은 어떤 일이 있어도 얼리-어답터가 되지 못한다
1. 어떤 사람(노드)를 기준으로, 이 사람이 얼리 어답터가 아니려면 이 사람과 친구인 모든 사람이 얼리-어답터여야만 한다
2. 반대로, 어떤 사람이 얼리-어답터이라면 친구의 얼리-어답터 유무는 중요하지 않다
- 친구의 친구가 얼리 어답터가 아니라면 문제가 생기겠지만, 이건 해당 친구 노드를 처리할 때 처리하고, 우선 직접 연결된 친구만 고려한다
3. 친구 없는 사람이라면, 자신이 얼리 어답터인지/아닌지에 조건이 붙지 않는다
4. 특정 사람(노드)을 root로 삼는 subtree 기준으로,
- 이 사람이 얼리-어답터이기 위한 최소 어답터 필요량
- 3번 정의에 따르면, 친구(자식 노드)의 얼리-어답터 유무는 중요하지 않다
- 얼리어답터가 아니기 위한 최소 어답터 필요량
- 2번 정의에 따르면, 모든 친구(자식)은 얼리-어답터여야 한다
- 이 두가지를 반환한다
- leaf 노드는 제한이 없으므로 얼리 어답터일때 1, 아닐때 0을 반환한다
5. 즉, 특정 사람(노드)이 얼리-어답터일 때 필요한 최소 어답터 수는
- 모든 자식들의 얼리/not-얼리 결과값 중 작은것의 합계 + 1(자기 자신) 이 된다
6. 특정 사람(노드)이 얼리-어답터가 아닐 때 필요한 최소 어답터 수는
- 모든 자식을듸 얼리 결과값의 합계 가 된다
7. 이 과정을 leaf 노드부터 시작해 root노드까지 진행하면, root가 얼리-어답터일때 / 아닐때 각각의 최솟값을 구할 수 있다
- 둘 중 작은 값을 반환한다
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;
import java.util.StringTokenizer;
public class Main {
static boolean[] isVisit;
static List<List<Integer>> tree;
public static void main(String[] args)throws Exception {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
int N = pint(br.readLine());
tree = new ArrayList<>();
for (int i = 0; i < N; i++) {
tree.add(new LinkedList<Integer>());
}
for (int i = 0; i < N-1; i++) {
StringTokenizer st = new StringTokenizer(br.readLine(), " ");
int n = pint(st.nextToken()) - 1;
int m = pint(st.nextToken()) - 1;
tree.get(n).add(m);
tree.get(m).add(n);
}
isVisit = new boolean[N];
int curNode=0;
isVisit[curNode]=true;
int[] ans = rec(curNode);
System.out.println(ans[0]>ans[1]?ans[1]:ans[0]);
}
static int[] rec(int curNode) {
if(curNode!=0 && tree.get(curNode).size()==1) {
return new int[] {1,0};
}
int iAmEA=1;
int iAmNotEA=0;
for(int nextNode : tree.get(curNode)) {
if(isVisit[nextNode])continue;
isVisit[nextNode]=true;
int[] tmp = rec(nextNode);
iAmEA += Math.min(tmp[1],tmp[0]);
iAmNotEA += tmp[0];
}
return new int[]{iAmEA,iAmNotEA};
}
static int pint(String s) {
return Integer.parseInt(s);
}
}