https://www.acmicpc.net/problem/9466
βοΈ λ¬Έμ
π λ¬Έμ ν΄κ²°
μ΄ λ¬Έμ λ μκ°λ³΄λ€ κ°λ¨νλ° μ΄λ ΅λ€.
μ μμ μ€ νλλ₯Ό κ·Έλ¦ΌμΌλ‘ ννν΄λ³΄μλ€.
κ·Έλ¦Όμ 보면, (1λ², 5λ²) -> 3λ² κ³Ό νμ μ΄λ£¨κ³ μΆμ΄νλ€. νμ§λ§ 3λ²μ νΌμ νμ νκΈΈ μνλ€.
μ΄λ κ² λλ©΄ 1λ² 5λ²μ νμ μ΄λ£° μ μκ² λλ€.
λ, 2λ²-> 1λ² -> 3λ²(νΌμ ν) μ΄λ―λ‘ 2λ²λ νμ μ΄λ£° μ μκ² λλ€.
4λ², 6λ², 7λ²μ μλ‘λ₯Ό κ°λ¦¬ν€κ³ μμΌλ―λ‘ νμ΄ μμ±μ΄ λλ€!
λμΆ© μ΄λμ λ μ΄ν΄ν λ°νμΌλ‘ 쑰건μ μ€μ νλ©΄ μλμ κ°λ€.
- νΌμ νμ νκ³ μΆμ΄νλ μ¬λμ μ νν μ¬λμ νμ μ΄λ£° μ μλ€.
- νμ μ΄λ£¨κΈ° μν΄μλ μλ‘λ₯Ό μ νν΄μΌλ§ νλ€. (μ κ·Έλ¦Ό 4, 6, 7λ²κ³Ό κ°μ΄)
λ¨Όμ μ΄ λ¬Έμ μμλ λ°©λ¬Έ μ¬λΆ λ°°μ΄κ³Ό, ν μμ± μ¬λΆ λ°°μ΄ μ΄λ κ² 2κ°μ§ λ°°μ΄μ΄ νμνλ€.
μλνλ©΄, λ°©λ¬Έμ¬λΆλ§ 체ν¬νλ€λ©΄ μ΄ νμμ΄ νμ μν΄μλμ§ μ μν΄μλμ§ μ μ μκΈ° λλ¬Έμ΄λ€.
boolean[][] visit, done; // λ°©λ¬Έ μ¬λΆ, ν μμ± μ¬λΆ
1λ² μ‘°κ±΄μ, μ λ ₯μ λ°μ λ μΈλ±μ€μ κ°λ¦¬ν€λ νμμ μΈλ±μ€κ° κ°μ κ²½μ° ν μμ± λ°°μ΄μ 체ν¬λ₯Ό ν΄μ€λ€. (μ½λ μΌλΆλΆ)
for(int i = 1; i <= N; i++){
arr[i] = Integer.parserInt(st.nextToken()); // μμμ StringTokenizerλ₯Ό μ
λ ₯ λ°μ μ½λλ μλ΅..
if(arr[i] == i){
done[i] = true; // μκΈ° μμ μ κ°λ¦¬ν€κ³ μμΌλ©΄ -> ν μμ± μ²΄ν¬!
count++; // νμ΄ μμ±λ νμ μ μ¦κ°
}
}
2λ² μ‘°κ±΄μ, μμ μ΄ κ°λ¦¬ν€λ νμμ΄ νμ μ΄λ£¬μ μ΄ μκ³ , μ΄λ―Έ λ°©λ¬Ένλ€λ 건 -> μ κ·Έλ¦Ό 4, 6, 7λ² νμμ μΌμ΄μ€μ΄λ―λ‘ νμ΄ μμ±μ΄ λ κ²μ΄λ€.
for(int i = 1; i <= N; i++) {
if(!done[i]) {
dfs(i);
}
}
-----------------------------
public static void dfs(int n){
// μ΄λ―Έ λ°©λ¬Έ νμ λ!
if(visit[n]){
done[n] = true; // ν νΈμ± μλ£νλ€κ³ μ²λ¦¬
count++; // ν νΈμ± μλ£ μΈμ μ¦κ°
}else{
// λ°©λ¬Ένμ§ μμμ λ -> λ°©λ¬Έ μ²λ¦¬!
visit[n] = true;
}
// λ€μ νμμ΄ ν κ²°μ±μ μμ§ λͺ»νμ κ²½μ°
if(!done[arr[n]]){
dfs(arr[n]);
}
// ν΄λΉ νμ λ°©λ¬Έ 체ν¬λ₯Ό ν΄μ νκ³ , ν μμ± μ¬λΆ 체ν¬νλ€. (μ΄λλ νμ΄ μλμλλΌλ κ·Έλ₯ 체ν¬λ₯Ό ν΄μ€λ€.)
visit[n] = false;
done[n] = true;
}
π₯ μ 체 μ½λ
import java.util.*;
import java.io.*;
public class Main{
static int[] arr;
static boolean[] visit, done; // λ°©λ¬Έ, ν νΈμ± μλ£ λ°°μ΄
static int count; // νμ΄ μμ±λ μΈμ μ
public static void main(String[] args) throws IOException {
BufferedReader bf = new BufferedReader(new InputStreamReader(System.in));
BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(System.out));
int T = Integer.parseInt(bf.readLine());
StringTokenizer st;
for(int p = 0; p < T; p++){
int n = Integer.parseInt(bf.readLine());
arr = new int[n+1];
visit = new boolean[n+1];
done = new boolean[n+1];
count = 0;
st = new StringTokenizer(bf.readLine());
for(int i=1; i<= n; i++){
arr[i] = Integer.parseInt(st.nextToken());
}
for(int i=1; i<= n; i++){
if(!done[i]){
dfs(i);
}
}
bw.write((n-count) + "\n");
}
bw.flush();
bw.close();
}
public static void dfs(int n){
// μ΄λ―Έ λ°©λ¬Έ νμ λ!
if(visit[n]){
done[n] = true; // ν νΈμ± μλ£νλ€κ³ μ²λ¦¬
count++; // ν νΈμ± μλ£ μΈμ μ¦κ°
}else{
// λ°©λ¬Ένμ§ μμμ λ -> λ°©λ¬Έ μ²λ¦¬!
visit[n] = true;
}
// λ€μ νμμ΄ ν κ²°μ±μ μμ§ λͺ»νμ κ²½μ°
if(!done[arr[n]]){
dfs(arr[n]);
}
visit[n] = false;
done[n] = true;
}
}