|V| = |E| + 1
트리의 루트를 1로 할 때, 각 노드의 부모는 어떻게 결정될까
static void input(){
n = sc.nextInt();
adj = new ArrayList[N + 1];
parent = new int[N+1];
for(int i=1;i<=N;i++) adj[i] = new ArrayList<>();
for(int i=1;i<N;i++){
int x = sc.nextInt(), y = sc.nextInt();
adj[x].add(y);
adj[y].add(x);
}
// 정점 x의 부모가 par, 였고, x의 children을 찾아주는 함수
static void dfs(int x, int par){
for(int y: adj[x]){
if(y == par) continue;
parent[y] = x;
dfs(y,x);
}
}
static void pro(){
dfs(1,-1);
for(int i=2;i<=N;i++)
sb.append(parent[i]).append('\n');
System.out.println(sb);
}
Rooted tree와 지울 노드가 주어진다. 노드 하나를 지우고 난 후 단말 노드(리프 노드)의 갯수를 세야한다.
정점 제거
정점이 사라진다? 정점과 이어진 간선들이 모두 사라진다 → 정점 X의 부모에서 X로 가는 간선 삭제 || 무시
트리의 단말 노드 개수 측정
<<큰 문제>> 를
Root의 자식 노드들의 subtree안에 있는 단말 노드의 개수 <<작은 문제>>의 정답을 이용해 구하자
단말 노드의 개수 세기
x가 단말 노드인 경우 : leaf[0] = 1
x가 단말 노드가 아닌 경우 : x의 자식들에 대해 leaf를 먼저 계산하고, 그의 합
leaf[X] 계산하는법
Root에서 DFS를 한다면, 노드 X에서 자식 Y에 대한 탐색을 끝나고 돌아오면 leaf[Y]가 계산되어 왔을테니 leaf[X]에 leaf[Y]를 누적해주면 된다.
static int N,root,erased;
static ArrayList<Integer>[] child;
static int[] leaf;
static void input(){
N = sc.nextInt();
child = new ArrayList[N];
leaf = new int[N];
for(int i=0;i<N;i++) child[i] = new ArrayList<>();
for(int i=0;i<N;i++){
int par = sc.nextInt();
if(par == -1){
root = i;
continue;
}
child[par].add(i);//자식 노드 기록
}
erased = sc.nextInt();
}
static void dfs(int x){
if(child[x].isEmpty()){
leaf[x] = 1;
}
for(int y : child[x]){
dfs(y);
leaf[x] += leaf[y];
}
}
static void pro(){
// TODO : erased와 그의 부모 사이의 연결을 끊어주기
for(int i=0;i<N;i++){
if(child[i].contains(erased)){
child[i].remove(child[i].indexOf(erased));
}
// TODO : erased가 root인 예외 처리하기
if(root != erased) dfs(root);
// TODO : 정답 출력하기
System.out.println(leaf[root]);
}