https://www.acmicpc.net/problem/15681
로직을 구현하는 것은 어렵지 않았는데 계속 메모리 초과가 나서 골치를 먹었던 문제였다.
makeTree
는 노드 간의 연결관계를 표현한 graph
를 바탕으로 재귀적으로 트리를 구성한다.
countSubtreeNodes
는 재귀적으로 nodeCount
에 노드별 서브 트리 노드 수를 저장한다.
메모리를 최소화하기 위해 List<Integer>[]
형태로 graph
,tree
를 정의하였다.
로직의 시간복잡도는 최대 이며, 이는 이 일때도 문제 시간 제한을 무난히
통과한다.
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.List;
import java.util.StringTokenizer;
import static java.lang.Integer.parseInt;
public class Main {
static int N, R, Q;
static List<Integer>[] graph, tree;
static int[] nodeCount;
public static void main(String[] args) throws IOException {
BufferedReader in = new BufferedReader(new InputStreamReader(System.in));
StringTokenizer st = new StringTokenizer(in.readLine());
N = parseInt(st.nextToken());
R = parseInt(st.nextToken());
Q = parseInt(st.nextToken());
graph = new List[N + 1];
tree = new List[N + 1];
for (int i = 0; i < graph.length; i++) {
graph[i] = new ArrayList<>();
tree[i] = new ArrayList<>();
}
nodeCount = new int[N + 1];
for (int i = 0; i < N - 1; i++) {
st = new StringTokenizer(in.readLine());
int u = parseInt(st.nextToken());
int v = parseInt(st.nextToken());
graph[u].add(v);
graph[v].add(u);
}
makeTree(R, 0);
countSubtreeNodes(R);
StringBuilder sb = new StringBuilder();
for (int i = 0; i < Q; i++) {
int node = parseInt(in.readLine());
sb.append(nodeCount[node] + "\n");
}
System.out.print(sb);
in.close();
}
static void makeTree(int current, int parent) {
for (Integer node : graph[current]) {
if (node != parent) {
tree[current].add(node);
makeTree(node, current);
}
}
}
static void countSubtreeNodes(int current) {
nodeCount[current] = 1;
for (Integer node : tree[current]) {
countSubtreeNodes(node);
nodeCount[current] += nodeCount[node];
}
}
}
좋은 글 감사합니다. 자주 올게요 :)