Skip to content

Commit 8415afe

Browse files
authored
Merge pull request #190 from AlgorithmWithGod/ShinHeeEul
[20250227] BOJ / P5 / 한동이는 영업사원! / 신희을
2 parents 565588c + 31c59cd commit 8415afe

File tree

1 file changed

+151
-0
lines changed

1 file changed

+151
-0
lines changed
Lines changed: 151 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,151 @@
1+
```java
2+
import java.io.*;
3+
import java.util.*;
4+
5+
public class Solution {
6+
7+
8+
static int N;
9+
static int min = Integer.MAX_VALUE;
10+
static ArrayList<Integer>[] lists;
11+
static int[][] parents;
12+
static int[] depths;
13+
static boolean[] visited;
14+
static int count = 0;
15+
static int logN;
16+
17+
public static void main(String[] args) throws Exception {
18+
19+
N = read();
20+
21+
logN = (int) (Math.log(N) / Math.log(2));
22+
lists = new ArrayList[N + 1];
23+
visited = new boolean[N + 1];
24+
parents = new int[N + 1][logN];
25+
depths = new int[N + 1];
26+
27+
for(int i = 1; i < N + 1; i++) lists[i] = new ArrayList<>();
28+
29+
for(int i = 1; i < N; i++) {
30+
31+
int a = read();
32+
int b = read();
33+
34+
lists[a].add(b);
35+
lists[b].add(a);
36+
}
37+
38+
// 1. dfs 돌면서 맵 만들기
39+
dfs(1);
40+
// 2. parents 배열 채우기
41+
for(int i = 1; i < logN; i++) {
42+
for(int j = 1; j <= N; j++) {
43+
parents[j][i] = parents[parents[j][i - 1]][i - 1];
44+
}
45+
}
46+
47+
int current = 1;
48+
int M = read();
49+
50+
for(int i = 0; i < M; i++) {
51+
int destination = read();
52+
int tmp = destination;
53+
54+
if(current == destination) continue;
55+
// 3. 높이 맞추기
56+
int dc = depths[current];
57+
int dd = depths[destination];
58+
59+
if(dc < dd) {
60+
int diff = dd - dc;
61+
count += diff;
62+
destination = up(destination, diff);
63+
} else if(dd < dc) {
64+
int diff = dc - dd;
65+
count += diff;
66+
current = up(current, diff);
67+
}
68+
// 4. lca
69+
count += (lca(current, destination) << 1);
70+
current = tmp;
71+
}
72+
73+
System.out.println(count);
74+
75+
}
76+
77+
public static int lca(int a, int b) {
78+
// 제일 높은 거부터 하나씩 보면서
79+
int cnt = 0;
80+
for(int i = logN - 1; i >= 0; i--) {
81+
if(parents[a][i] == parents[b][i]) continue;
82+
83+
a = parents[a][i];
84+
b = parents[b][i];
85+
86+
cnt += Math.pow(2, i);
87+
}
88+
89+
return a == b ? cnt : cnt + 1;
90+
91+
}
92+
93+
public static int up(int current, int diff) {
94+
for(int i = 0; (1 << i) <= diff; i++) {
95+
int bit = (1 << i);
96+
if((bit | diff) == diff) {
97+
current = parents[current][i];
98+
}
99+
}
100+
return current;
101+
}
102+
103+
public static void dfs(int start) {
104+
Stack<Node> stack = new Stack<>();
105+
106+
stack.add(new Node(start, 1));
107+
visited[start] = true;
108+
while(!stack.isEmpty()) {
109+
Node node = stack.pop();
110+
111+
int val = node.val;
112+
int depth = node.depth;
113+
depths[val] = depth;
114+
115+
for(int child : lists[val]) {
116+
if(visited[child]) continue;
117+
parents[child][0] = val;
118+
visited[child] = true;
119+
stack.add(new Node(child, depth + 1));
120+
}
121+
}
122+
}
123+
124+
static class Node {
125+
int val;
126+
int depth;
127+
128+
public Node(int val, int depth) {
129+
this.val = val;
130+
this.depth = depth;
131+
}
132+
}
133+
134+
private static int read() throws Exception {
135+
int d, o;
136+
boolean negative = false;
137+
d = System.in.read();
138+
139+
if (d == '-') {
140+
negative = true;
141+
d = System.in.read();
142+
}
143+
o = d & 15;
144+
145+
while ((d = System.in.read()) > 32)
146+
o = (o << 3) + (o << 1) + (d & 15);
147+
148+
return negative? -o:o;
149+
}
150+
}
151+
```

0 commit comments

Comments
 (0)