๋ฃจํธ๊ฐ ์๋ ํธ๋ฆฌ(rooted tree)๊ฐ ์ฃผ์ด์ง๊ณ , ๊ทธ ํธ๋ฆฌ ์์ ๋ ์ ์ ์ด ์ฃผ์ด์ง ๋ ๊ทธ๋ค์ ๊ฐ์ฅ ๊ฐ๊น์ด ๊ณตํต ์กฐ์(Nearest Common Anscestor)์ ๋ค์๊ณผ ๊ฐ์ด ์ ์๋ฉ๋๋ค.
* ๋ ๋ ธ๋์ ๊ฐ์ฅ ๊ฐ๊น์ด ๊ณตํต ์กฐ์์, ๋ ๋ ธ๋๋ฅผ ๋ชจ๋ ์์์ผ๋ก ๊ฐ์ง๋ฉด์ ๊น์ด๊ฐ ๊ฐ์ฅ ๊น์(์ฆ ๋ ๋ ธ๋์ ๊ฐ์ฅ ๊ฐ๊น์ด) ๋ ธ๋๋ฅผ ๋งํฉ๋๋ค.
์๋ฅผ ๋ค์ด 15์ 11๋ฅผ ๋ชจ๋ ์์์ผ๋ก ๊ฐ๋ ๋ ธ๋๋ 4์ 8์ด ์์ง๋ง, ๊ทธ ์ค ๊น์ด๊ฐ ๊ฐ์ฅ ๊น์(15์ 11์ ๊ฐ์ฅ ๊ฐ๊น์ด) ๋ ธ๋๋ 4 ์ด๋ฏ๋ก ๊ฐ์ฅ ๊ฐ๊น์ด ๊ณตํต ์กฐ์์ 4๊ฐ ๋ฉ๋๋ค.
๋ฃจํธ๊ฐ ์๋ ํธ๋ฆฌ๊ฐ ์ฃผ์ด์ง๊ณ , ๋ ๋ ธ๋๊ฐ ์ฃผ์ด์ง ๋ ๊ทธ ๋ ๋ ธ๋์ ๊ฐ์ฅ ๊ฐ๊น์ด ๊ณตํต ์กฐ์์ ์ฐพ๋ ํ๋ก๊ทธ๋จ์ ์์ฑํ์ธ์
์ ๋ ฅ
์ฒซ ์ค์ ํ ์คํธ ์ผ์ด์ค์ ๊ฐ์ T๊ฐ ์ฃผ์ด์ง๋๋ค.
๊ฐ ํ ์คํธ ์ผ์ด์ค๋ง๋ค, ์ฒซ์งธ ์ค์ ํธ๋ฆฌ๋ฅผ ๊ตฌ์ฑํ๋ ๋ ธ๋์ ์ N์ด ์ฃผ์ด์ง๋๋ค. (2 โค N โค 10,000)
๊ทธ๋ฆฌ๊ณ ๊ทธ ๋ค์ N-1๊ฐ์ ์ค์ ํธ๋ฆฌ๋ฅผ ๊ตฌ์ฑํ๋ ๊ฐ์ ์ ๋ณด๊ฐ ์ฃผ์ด์ง๋๋ค. ํ ๊ฐ์ ๋น ํ ์ค์ ๋ ๊ฐ์ ์ซ์ A B ๊ฐ ์์๋๋ก ์ฃผ์ด์ง๋๋ฐ, ์ด๋ A๊ฐ B์ ๋ถ๋ชจ๋ผ๋ ๋ป์ ๋๋ค. (๋น์ฐํ ์ ์ ์ด N๊ฐ์ธ ํธ๋ฆฌ๋ ํญ์ N-1๊ฐ์ ๊ฐ์ ์ผ๋ก ์ด๋ฃจ์ด์ง๋๋ค!) A์ B๋ 1 ์ด์ N ์ดํ์ ์ ์๋ก ์ด๋ฆ ๋ถ์ฌ์ง๋๋ค.
ํ ์คํธ ์ผ์ด์ค์ ๋ง์ง๋ง ์ค์ ๊ฐ์ฅ ๊ฐ๊น์ด ๊ณตํต ์กฐ์์ ๊ตฌํ ๋ ๋ ธ๋๊ฐ ์ฃผ์ด์ง๋๋ค.
์ถ๋ ฅ
๊ฐ ํ ์คํธ ์ผ์ด์ค ๋ณ๋ก, ์ฒซ ์ค์ ์ ๋ ฅ์์ ์ฃผ์ด์ง ๋ ๋ ธ๋์ ๊ฐ์ฅ ๊ฐ๊น์ด ๊ณตํต ์กฐ์์ ์ถ๋ ฅํฉ๋๋ค.
๐ก ์ฃผ์ด์ง ์ซ์์ depth๋ฅผ ๊ตฌํจ
๐ก depth๊ฐ ๋ค๋ฅด๋ค๋ฉด, ํฐ ์ซ์๊ฐ ๋ถ๋ชจ๋
ธ๋๋ก ์ฌ๋ผ๊ฐ depth๊ฐ ๊ฐ์์ง๊ฒ ํจ
๐ก depth๊ฐ ์๋ก ๊ฐ๋ค๋ฉด, ๊ฐ์ ์ซ์๊ฐ ๋์ฌ๋๊น์ง ๋ถ๋ชจ๋
ธ๋๋ก ์ฌ๋ผ๊ฐ
1) ์ฃผ์ด์ง ์ซ์์ depth๋ฅผ ๊ตฌํจ
static int depth(int node) {
int dep = 0;
int cur = node;
while(cur != 0) {
dep++;
cur = parent[cur];
}
return dep-1;
}
2) depth๊ฐ ๋ค๋ฅด๋ค๋ฉด, ํฐ ์ซ์๊ฐ ๋ถ๋ชจ๋ ธ๋๋ก ์ฌ๋ผ๊ฐ depth๊ฐ ๊ฐ์์ง๊ฒ ํจ
if(aDepth > bDepth) {
while(aDepth != bDepth) {
aDepth--;
a = parent[a];
}
} else if(bDepth > aDepth) {
while(bDepth != aDepth) {
bDepth--;
b = parent[b];
}
}
3) depth๊ฐ ์๋ก ๊ฐ๋ค๋ฉด, ๊ฐ์ ์ซ์๊ฐ ๋์ฌ๋๊น์ง ๋ถ๋ชจ๋ ธ๋๋ก ์ฌ๋ผ๊ฐ
while(a!=b) {
a = parent[a];
b = parent[b];
}
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.IOException;
public class Graph_4 {
static int[] parent;
public static void main(String[] args) throws IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
int T = Integer.parseInt(br.readLine());
while(T-->0) {
int N = Integer.parseInt(br.readLine());
parent = new int[N+1];
String[] s;
for(int i=0; i<N-1; i++) {
s = br.readLine().split(" ");
parent[Integer.parseInt(s[1])] = Integer.parseInt(s[0]);
}
s = br.readLine().split(" ");
int a = Integer.parseInt(s[0]);
int b = Integer.parseInt(s[1]);
int aDepth = depth(a);
int bDepth = depth(b);
System.out.println(find(a,b,aDepth,bDepth));
}
}
static int depth(int node) {
int dep = 0;
int cur = node;
while(cur != 0) {
dep++;
cur = parent[cur];
}
return dep-1;
}
static int find(int a, int b, int aDepth, int bDepth) {
if(aDepth > bDepth) {
while(aDepth != bDepth) {
aDepth--;
a = parent[a];
}
} else if(bDepth > aDepth) {
while(bDepth != aDepth) {
bDepth--;
b = parent[b];
}
}
while(a!=b) {
a = parent[a];
b = parent[b];
}
return a;
}
}
์ฑ๊ณตโจ