[백준 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