-
11725 트리의 부모 찾기 (자바)백준/트리 2022. 2. 19. 16:15
import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamReader; import java.util.ArrayList; import java.util.StringTokenizer; public class Main { static boolean check []; static int parents []; static ArrayList<ArrayList<Integer>> list; public static void main(String args[]) throws IOException{ BufferedReader br = new BufferedReader(new InputStreamReader(System.in)); int N = Integer.parseInt(br.readLine()); check = new boolean [N+1]; parents = new int[N+1]; list = new ArrayList<ArrayList<Integer>>(); for(int i = 0; i<=N; i++) { list.add(new ArrayList<Integer>()); } int M = N; while(M-->1) { StringTokenizer st = new StringTokenizer(br.readLine(), " " ); int one = Integer.parseInt(st.nextToken()); int two = Integer.parseInt(st.nextToken()); list.get(one).add(two); list.get(two).add(one); } dfs(1); for(int i = 2; i<=N; i++) { System.out.println(parents[i]); } } public static void dfs(int a) { if(check[a]) { return; } check[a] = true; for(int b : list.get(a)) { if(!check[b]) { parents[b] = a; dfs(b); } } } }
# 트리
트리 구조를 만들 때,
리스트<리스트> 형식을 사용했다.
예시에 나온 값으로
7
1 6
6 3
3 5
4 1
2 4
4 7만들어진 트리 구조를 보면,
위와 같은 구조인데, 실제로 이클립스에서
예시로 주어진
7
1 6
6 3
3 5
4 1
2 4
4 7이 값들로 리스트 형식 트리(list)를 만들면
while(M-->1) { StringTokenizer st = new StringTokenizer(br.readLine(), " " ); int one = Integer.parseInt(st.nextToken()); int two = Integer.parseInt(st.nextToken()); list.get(one).add(two); list.get(two).add(one); }
이런 식으로
앞의 값 1은 one 으로, 뒤의 값 6은 two 로 받아서
리스트 형식의 트리 구조에 잘 넣어줘서 완성했다.
리스트 형식으로 만든 트리(list)를 찍어보면
이런 형식으로 나온다.
즉, 트리의 인덱스 0 에는 아무 값도 넣지 않는 것으로 하고,
예시에 이렇게 나온 것처럼
트리 노드 1은 노드 4,6 과 연결되고,
노드 2는 4와
노드 3은 6,5 와 연결됨을 알 수 있다.
#dfs
1) dfs 메서드 설명
dfs 코드를 살펴보면 아래와 같다.
public static void dfs(int a) { if(check[a]) { return; } check[a] = true; for(int b : list.get(a)) { if(!check[b]) { parents[b] = a; dfs(b); } } }
main 메서드에서 dfs(1) 을 실행하도록 했는데,
dfs 메서드 내의
for(int b : list.get(a)) { if(!check[b]) { parents[b] = a; dfs(b); } }
이 코드를 통해서,
1의 자식 노드인 4,6 에 대해서
parents 배열의 값을 1로 만들었다.
즉, parents[4] = parents[6] = 1 이다.
그런 다음,
dfs(b) 를 재귀적으로 실행하도록 하여
4와 6의 자식 노드에 대해서도 dfs 를 진행하면서
parents 배열에 값을 채워넣었다.
그리고 boolean 형 check 배열을 만들어서 한 번 지나온 노드들은 true 표시해서
parents 배열에 값이 한 번 채워지고 난 다음에는 반복적으로 값을 채워 넣지 않도록 했다.
2) dfs 메서드 진행 순서
dfs 메서드 바로 아래, a 값을 찍어보도록 코드를 만들었다.
public static void dfs(int a) { System.out.println("순서 : "+ a);
그랬더니 그 결과로
이렇게 나왔다.
즉, 1 6 3 5 4 2 7 순서로 dfs가 이뤄졌음을 알 수 있다.
이 그림에서 알 수 있듯이
맨 위의 노드 1에서부터 시작해서 오른쪽의 노드 6으로 가서 맨 아래 5까지 갔다가
다시 올라온 뒤 왼쪽 4, 또 왼쪽 2, 오른쪽 7로 이동하면서 진행된 것이다.
# 주의점
꼭 알아야 할 부분이 있다.
코드에서 보면
int M = N; while(M-->1)
이 부분이 있다.
이때, N 은 7이였고, M 역시 처음에는 7이 된다.
그런데 while 문을 M --> 1 조건으로 다 돌고 나면 M 은 0이 된다.
이것을 꼭 주의하자!
참고 자료 :
https://log-laboratory.tistory.com/65
[백준] 11725번 트리의 부모노드 찾기
문제 출처 https://www.acmicpc.net/problem/11725 11725번: 트리의 부모 찾기 루트 없는 트리가 주어진다. 이때, 트리의 루트를 1이라고 정했을 때, 각 노드의 부모를 구하는 프로그램을 작성하시오. www.acmicpc
log-laboratory.tistory.com