• toc {:toc}

문제 ν™•μΈν•˜κΈ°

풀이

λ¬Έμ œμ— λŒ€ν•œ μ„€λͺ…을 μ‹œκ°ν™”ν•˜λ©΄ λ‹€μŒκ³Ό κ°™λ‹€.

image

λ‹€μŒμ˜ κ·Έλž˜ν”„ ꡬ쑰의 νŠΉμ§•μ€ λ‹€μŒκ³Ό κ°™λ‹€.

  1. λ°©ν–₯이 μžˆλ‹€.
  2. 사이클이 λ°œμƒν•  수 μžˆλ‹€.
  3. 자기 μžμ‹ μ„ μ„ νƒν•˜λŠ” 루프가 μžˆλ‹€.

보닀 더 μ‰½κ²Œ μ‹œκ°ν™”ν•˜λ©΄ λ‹€μŒκ³Ό κ°™λ‹€.

image

1, 2, 3, 5λŠ” 3이 자기 μžμ‹ μ„ μ„ νƒν–ˆκΈ° λ•Œλ¬Έμ— 사이클이 λ§Œλ“€μ–΄μ§€μ§€ μ•ŠλŠ”λ‹€. 반면, 4, 6, 7은 사이클이 λ§Œλ“€μ–΄μ Έ κ²°κ³Όκ°’μ˜ λŒ€μƒμ—μ„œ μ œμ™Έλœλ‹€.

풀이 방식은 λ‹€μŒκ³Ό κ°™λ‹€.

  1. 1λΆ€ν„° 전체 수λ₯Ό λ°˜λ³΅ν•˜μ—¬ λ°©λ¬Έν•œ 적이 μ—†λ‹€λ©΄ cycle ν•¨μˆ˜μ— λ„£μ–΄μ€€λ‹€.
  2. cycle ν•¨μˆ˜λ₯Ό 톡해 사이클을 체크해쀀닀.
  3. 사이클에 λ“€μ–΄κ°€ μžˆμ§€ μ•Šμ€ 수λ₯Ό 체크해쀀닀.

cycle ν•¨μˆ˜μ˜ 풀이 방식은 λ‹€μŒκ³Ό κ°™λ‹€.

  1. xλ₯Ό 체크값이라 μƒκ°ν•œλ‹€. λ°©λ¬Έμ²΄ν¬λŠ” μ²΄ν¬κ°’μœΌλ‘œ μ§„ν–‰ν•œλ‹€. vis[cur] = x;
  2. ν•΄λ‹Ή ν•¨μˆ˜ μ•ˆμ—μ„œ 즉, μœ„ κ·Έλ¦Όμ—μ„œ x=4이고 사이클을 λŒμ•„ λ‹€μ‹œ 4둜 μ΄λ™ν•œ κ²½μš°μ΄λ‹€. ν•΄λ‹Ή 경우 체크값이 x이기 λ•Œλ¬Έμ— vis[cur]== x 라면 -1둜 μ‚¬μ΄ν΄μ΄λΌλŠ” 것을 체크해쀀닀.
  3. λ§Œμ•½, ν˜„μž¬ x=6 일 λ•Œλ₯Ό μƒκ°ν•˜λ©΄ x=4일 λ•Œ 이미 사이클이 ν•œ 번 체크가 된 상황이닀. λ•Œλ¬Έμ— 사이클을 λ‹€μ‹œ 확인할 ν•„μš”μ—†μ΄ λ°˜ν™˜ν•œλ‹€.
  4. vis κ°€ -1이 μ•„λ‹Œ 경우, 즉, 사이클이 μ•„λ‹Œ 경우 res++을 ν†΅ν•΄μ„œ νŒ€μ— ν•΄λ‹Ήν•˜μ§€ μ•ŠλŠ” 경우λ₯Ό μ²΄ν¬ν•œλ‹€.
#include <bits/stdc++.h>
using namespace std;
 
int vis[100005];
int students[100005];
int n;
 
void cycle(int x){
    int cur = x;
    while(true){
        vis[cur] = x;
        cur = students[cur];
        if(vis[cur] == x){
            while(vis[cur] != -1){
                vis[cur] = -1;
                cur = students[cur];
            }
            return;
        }
        else if(vis[cur] != 0) return;
    }
}
 
int main(){
    ios::sync_with_stdio(false);
    cin.tie(0);
 
    int T;
 
    cin >> T;
 
    while(T--){
        cin >> n;
        fill(vis, vis+n+1, 0);
        for(int i=1; i<=n; i++){
            cin >> students[i];
        }
        int res = 0;
        for(int i=1; i<=n; i++){
            if(vis[i] == 0) cycle(i);
        }
        for(int i=1; i<=n; i++){
            if(vis[i] != -1) res++; 
        }
        cout << res << '\n';
    }
 
    return 0;
}