https://www.acmicpc.net/problem/11725
트리의 부모 찾기
시간 제한메모리 제한제출정답맞힌 사람정답 비율
| 1 초 | 256 MB | 101747 | 46543 | 32592 | 43.306% |
문제
루트 없는 트리가 주어진다. 이때, 트리의 루트를 1이라고 정했을 때, 각 노드의 부모를 구하는 프로그램을 작성하시오.
입력
첫째 줄에 노드의 개수 N (2 ≤ N ≤ 100,000)이 주어진다. 둘째 줄부터 N-1개의 줄에 트리 상에서 연결된 두 정점이 주어진다.
출력
첫째 줄부터 N-1개의 줄에 각 노드의 부모 노드 번호를 2번 노드부터 순서대로 출력한다.
예제 입력 1
7
1 6
6 3
3 5
4 1
2 4
4 7
예제 출력 1
4
6
1
3
1
4
예제 입력 2
12
1 2
1 3
2 4
3 5
3 6
4 7
4 8
5 9
5 10
6 11
6 12
예제 출력 2
1
1
2
3
3
4
4
5
5
6
6
처음에 나는 Find-Union을 생각하여 나오는 노드 중 하나를 부모로 지정하려고 하였다. 밑에 코드와 같이
- 입력받은 노드 2개중에 하나가 parent가 지정돼있는지 확인
- 지정이 안돼있으면 둘 중하나가 나머지의 부모이다.
import java.io.*;
import java.util.*;
class Main {
public static void main(String[] args)throws IOException {
BufferedReader br= new BufferedReader(new InputStreamReader(System.in));
int N =Integer.parseInt(br.readLine());
int[] parent = new int[N+1];
Arrays.fill(parent,-1);
parent[1] = 0;
for(int i = 0 ; i <N-1;i++){
String[] input = br.readLine().split(" ");
int front = Integer.parseInt(input[0]);
int back = Integer.parseInt(input[1]);
if(parent[front]!=-1){
parent[back] =front;
}else{
parent[front] = back;
}
}
for(int i = 2 ; i<=N;i++){
System.out.println(parent[i]);
}
}
}
이런식으로 간단하게 부모 노드를 정하려고 하였다.
이렇게 하면 예제문제는 간단하게 풀리게 됨.
그렇지만 예제는 부모노드가 정의된 노드 순서대로 예제를 아주 이쁘게 주었기 때문에 문제가 발생하지 않는다.
예를 들면
7
1 6
6 3
3 5
4 1
2 4
4 7
이렇게 되면
1 6 // 1은 root로 지정돼있으므로, 1은 6의 부모이다.
6 3 // 6은 부모가 1로 지정돼있으므로, 6은 3의 부모이다.
3 5 // 3은 부모가 6으로 지정돼있으므로, 3은 5의 부모이다.
4 1 // ...
2 4 // ...
4 7 // ...
같은 방식으로 끝까지 도달하게 되면 부모 노드를 저장하게 된다.
하지만 만약에
3 5
6 3
4 1
2 4
4 7
이런식으로 첫 번째 줄과, 두 번째 줄이 바뀌게 된다면 어떻게 될까?
그러면 3이랑 5는 둘 다 부모가 아직 없기 때문에 , 꼬여버리게 된다.
그래서 어떻게 할까? 하다가 나는 BFS로 문제를 풀어보았다.
import java.io.*;
import java.util.*;
class Main {
public static void main(String[] args)throws IOException {
BufferedReader br= new BufferedReader(new InputStreamReader(System.in));
int N =Integer.parseInt(br.readLine());
boolean[] visited = new boolean[N+1];
int[] parent = new int[N+1];
ArrayList<Integer>[] adList = new ArrayList[N+1];
for(int i = 0; i <=N ; i++){
adList[i]=new ArrayList<>();
}
for(int i = 0 ; i < N-1 ; i ++){
String[] input= br.readLine().split(" ");
int v1 = Integer.parseInt(input[0]);
int v2 = Integer.parseInt(input[1]);
adList[v1].add(v2);
adList[v2].add(v1);
}
ArrayDeque<Integer> queue= new ArrayDeque<>();
queue.add(1);
while(!queue.isEmpty()){
int now = queue.poll();
for(int next: adList[now]){
if(!visited[next]){
visited[next] =true;
parent[next] = now;
queue.add(next);
}
}
}
for(int i = 2 ; i <= N ; i++){
System.out.println(parent[i]);
}
}
}
'코팅테스트' 카테고리의 다른 글
| [코딩 테스트] 좋은 친구 (4) | 2025.02.04 |
|---|---|
| [코딩 테스트] 오큰수 (2) | 2025.02.04 |
| [코딩 테스트] 칸토어 집합 (2) | 2025.01.26 |
| [코딩 테스트] 연산자 끼워넣기 (2) | 2025.01.25 |
| [코딩 테스트] 연구소 (5) | 2025.01.25 |