문제
현민이는 트리 모양의 길 위에서 오토바이를 타고 전단지를 돌리려고 한다. 현민이의 목표는 케니소프트에서 출발하여 모든 노드에 전단지를 돌리고, 다시 케니소프트로 돌아오는 것이다. 현민이는 힘이 좋기 때문에 현재 노드에서 거리가 D 이하인 모든 노드에 전단지를 돌릴 수 있다.
날씨가 매우 덥기 때문에, 현민이는 최소한만 이동해서 목표를 달성하고 싶다! 현민이를 위해 현민이가 이동해야 하는 총 거리를 구해주자.
접근 방식
D 이하인 모든 노드에 전단지를 돌릴 수 있다는 말을 해석하면 트리의 리프노드로부터 D거리 미만인 노드를 탐색하지 않아도 된다는 뜻이다.
따라서 먼저 시작 점인 S에서 시작해서 dfs 탐색하여 각 노드의 높이를 구한다.
이 때 리프노드의 높이는 0이고, 높이가 D이상인 노드들을 탐색해야 한다.
왕복 간선의 갯수는 시작점을 제외한 방문노드의 갯수 * 2이므로 높이가 D 이상인 노드 중 시작점이 아닌 노드의 갯수에 2를 곱한 값을 출력한다.
코드
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.List;
import java.util.StringTokenizer;
public class Main_19542 {
static int N,S,D;
static List<List<Integer>> edgeList;
static int depth[];
static int cnt;
public static void main(String[] args) throws IOException{
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
StringTokenizer st = new StringTokenizer(br.readLine());
N = Integer.parseInt(st.nextToken());
S = Integer.parseInt(st.nextToken());
D = Integer.parseInt(st.nextToken());
edgeList = new ArrayList<>();
for(int i=0;i<=N;i++) {
edgeList.add(new ArrayList<>());
}
for(int i=0;i<N-1;i++) {
st = new StringTokenizer(br.readLine());
int x = Integer.parseInt(st.nextToken());
int y = Integer.parseInt(st.nextToken());
edgeList.get(x).add(y);
edgeList.get(y).add(x);
}
cnt = 0;
depth = new int[N+1];
dfs(S,-1);
System.out.println(cnt*2);
}
public static int dfs(int node, int preNode) {
for(int nextNode : edgeList.get(node)) {
if(nextNode != preNode) {
depth[node] = Math.max(depth[node], dfs(nextNode,node)+1);
}
}
if(node!=S && depth[node] >= D) {
cnt++;
}
return depth[node];
}
}