[백준 9466 : JAVA] 텀 프로젝트 / DFS
문제

풀이
이 문제는 모든 정점은 한 번씩만 탐색되어야 한다는게 핵심이다. 첫 번째 예제를 살펴보자.

가장 먼저 1번 노드부터 탐색을 진행한다.

1번 노드부터 탐색을 시작했더니 3번 노드가 사이클을 형성한다는걸 찾았다.
이게 이 문제의 포인트인데, 사이클 형성 여부를 찾기 위해 가장 쉽게 생각해볼 수 있는 방법은 다음과 같다.
- 처음 탐색을 시작한 노드 == 마지막으로 탐색할 노드
위의 방법으로 탐색을 진행하게 된다면 중복 탐색이 많이 발생하게 된다는 단점이 있다.
1번 노드가 사이클이 형성되지 않는단 걸 알지만, 다음 2번 노드의 탐색을 진행할 때 2 - 1 -3 으로 1번과 똑같은 탐색을 진행하게 된다.
다음 그림을 보자.

조건을 아래와 같이 바꾼다.
다음 노드가 탐색 시작 노드와 같은지 ---------> 다음 노드가 탐색을 통해 거쳐왔던 노드 중 하나와 같은지
private static int dfs(int start, int current, int depth) { // ...중략 if (check[next] != 0) { if (start == firstParent[next]) return depth - check[next] + 1; else return 0; } // ...중략 }
코드
import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamReader; import java.util.ArrayList; import java.util.List; import java.util.StringTokenizer; public class Main { private static BufferedReader br = new BufferedReader(new InputStreamReader(System.in)); private static int T; private static int[] edge; private static int[] check; private static int[] firstParent; public static void main(String[] args) throws IOException { T = Integer.parseInt(br.readLine()); while (T-- > 0) { int n = Integer.parseInt(br.readLine()); firstParent = new int[n + 1]; check = new int[n + 1]; edge = new int[n + 1]; StringTokenizer st = new StringTokenizer(br.readLine()); for (int j = 1; j <= n; j++) edge[j] = Integer.parseInt(st.nextToken()); int count = 0; for (int i = 1; i <= n; i++) { if (check[edge[i]] == 0) count += dfs(i, i, 1); } System.out.println(n - count); } br.close(); } private static int dfs(int start, int current, int depth) { check[current] = depth; firstParent[current] = start; int next = edge[current]; if (check[next] != 0) { // 방문했던 노드라면, 다음에 방문할 노드를 확인하여 사이클 형성 여부를 확인한다. if (start == firstParent[next]) return depth - check[next] + 1; else return 0; } return dfs(start, next, depth + 1); } }
'Algorithm > Baekjoon' 카테고리의 다른 글
[백준 13913 : JAVA] 숨바꼭질 4 / BFS (0) | 2020.09.30 |
---|---|
[백준 17141 : JAVA] 연구소 2 / BFS + 조합 (0) | 2020.09.27 |
[백준 11438 : JAVA] LCA 2 / 최소 공통 조상 (0) | 2020.09.11 |
[백준 13418 : JAVA] 학교 탐방하기 / MST (0) | 2020.09.09 |
[백준 2206 : JAVA] 벽 부수고 이동하기 / BFS (0) | 2020.09.08 |
댓글
이 글 공유하기
다른 글
-
[백준 13913 : JAVA] 숨바꼭질 4 / BFS
[백준 13913 : JAVA] 숨바꼭질 4 / BFS
2020.09.30 -
[백준 17141 : JAVA] 연구소 2 / BFS + 조합
[백준 17141 : JAVA] 연구소 2 / BFS + 조합
2020.09.27 -
[백준 11438 : JAVA] LCA 2 / 최소 공통 조상
[백준 11438 : JAVA] LCA 2 / 최소 공통 조상
2020.09.11 -
[백준 13418 : JAVA] 학교 탐방하기 / MST
[백준 13418 : JAVA] 학교 탐방하기 / MST
2020.09.09
댓글을 사용할 수 없습니다.