[java]공통조상 - SWEA 1248
풀이
문제 해석을 하자면,
- 두개의 정점이 주어지면 이것의 공통조상을 구하고, 해당 서브트리의 크기를 도출하라.
- 정점의 번호는 1부터 V까지의 정수이며, 루트 정점은 항상 1번이다.
- 간선은 항상 “부모 자식” 순서이다.
풀이
- 트리를 잘 알고있다면 생각보다 쉬운 문제이다.
- 이진트리라서 E가 별로 크지않다. 이는 희소행렬로 볼 수 있고, 연결리스트를 사용하는게 좋다.
-
2개 함수 구현하자
- 부모 찾기
- 따로 visited 배열을 만들어서 방문할때마다 ++를 했고,
- 2회 방문했을시 공통조상으로 구했다.
- BFS or DFS 로 서브트리 크기 구하기 -> 자기자신(+1) 포함
- 간단해서 생략
- 부모 찾기
코드
public static int result;
public static void dfs(int root, List<Integer>[] inArr) {
//base condition
List<Integer> list = inArr[root];
if(list.isEmpty()) return;
//recursion
for(int num : list) {
result++;
dfs(num, inArr);
}
}
public static int findAncestor(int[] pChkArr, int first, int second, int V) {
int answer = 0;
int[] visited = new int[V+1]; // 매번 새로 할당 (0)
visited[first]++;
visited[second]++;
while(true) {
// 종료시점
if(visited[first] == 2) {
answer = first;
break;
} else if(visited[second] == 2) {
answer = second;
break;
}
// 1 은 root 입니다.
if(first != 1) {
first = pChkArr[first];
visited[first]++;
}
if(second != 1) {
second = pChkArr[second];
visited[second]++;
}
}
return answer;
}
public static void main(String args[]) throws Exception
{
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
StringBuilder sb = new StringBuilder();
int T = Integer.parseInt(br.readLine());
for(int t = 1; t <= T; t++)
{
//input
StringTokenizer stk = new StringTokenizer(br.readLine(), " ");
int V = Integer.parseInt(stk.nextToken());
int E = Integer.parseInt(stk.nextToken());
int first = Integer.parseInt(stk.nextToken());
int second = Integer.parseInt(stk.nextToken());
stk = new StringTokenizer(br.readLine(), " ");
List<Integer>[] inArr = new ArrayList[V+1]; // 매번 새로할당
for(int i=0; i<V+1; i++) inArr[i] = new ArrayList<>();
int[] pChkArr = new int[V+1];
result = 1; //init
for(int i=0; i<E; i++) {
int parent = Integer.parseInt(stk.nextToken());
int child = Integer.parseInt(stk.nextToken());
inArr[parent].add(child); // 양방향 X
pChkArr[child] = parent; // 부모 기록
}
//run
// 1. 조상 부모 구하기
int ancestor = findAncestor(pChkArr, first, second, V);
// 2. 서브트리 크기 구하기
dfs(ancestor, inArr);
sb.append("#").append(t).append(" ").append(ancestor).append(" ").append(result).append("\n");
}
//ouput
System.out.print(sb);
}
느낀점
생략
댓글남기기