πŸ• Baaaaaarking/0x09κ°• - BFS

[BOJ][C++] λ°±μ€€ 9466번: ν…€ ν”„λ‘œμ νŠΈ

선달 2023. 5. 4. 23:08
λ°˜μ‘ν˜•

https://www.acmicpc.net/problem/9466

 

9466번: ν…€ ν”„λ‘œμ νŠΈ

이번 가을학기에 '문제 ν•΄κ²°' κ°•μ˜λ₯Ό μ‹ μ²­ν•œ 학생듀은 ν…€ ν”„λ‘œμ νŠΈλ₯Ό μˆ˜ν–‰ν•΄μ•Ό ν•œλ‹€. ν”„λ‘œμ νŠΈ νŒ€μ› μˆ˜μ—λŠ” μ œν•œμ΄ μ—†λ‹€. 심지어 λͺ¨λ“  학생듀이 λ™μΌν•œ νŒ€μ˜ νŒ€μ›μΈ κ²½μš°μ™€ κ°™μ΄ ν•œ νŒ€λ§Œ μžˆμ„

www.acmicpc.net

 

문제

이번 가을학기에 '문제 ν•΄κ²°' κ°•μ˜λ₯Ό μ‹ μ²­ν•œ 학생듀은 ν…€ ν”„λ‘œμ νŠΈλ₯Ό μˆ˜ν–‰ν•΄μ•Ό ν•œλ‹€. ν”„λ‘œμ νŠΈ νŒ€μ› μˆ˜μ—λŠ” μ œν•œμ΄ μ—†λ‹€. 심지어 λͺ¨λ“  학생듀이 λ™μΌν•œ νŒ€μ˜ νŒ€μ›μΈ κ²½μš°μ™€ κ°™μ΄ ν•œ νŒ€λ§Œ μžˆμ„ μˆ˜λ„ μžˆλ‹€. ν”„λ‘œμ νŠΈ νŒ€μ„ κ΅¬μ„±ν•˜κΈ° μœ„ν•΄, λͺ¨λ“  학생듀은 ν”„λ‘œμ νŠΈλ₯Ό ν•¨κ»˜ν•˜κ³  싢은 ν•™μƒμ„ μ„ νƒν•΄μ•Ό ν•œλ‹€. (단, 단 ν•œ λͺ…λ§Œ 선택할 수 μžˆλ‹€.) ν˜Όμž ν•˜κ³  μ‹Άμ–΄ν•˜λŠ” 학생은 자기 μžμ‹ μ„ μ„ νƒν•˜λŠ” 것도 κ°€λŠ₯ν•˜λ‹€.

학생듀이(s1, s2, ..., sr)이라 ν•  λ•Œ, r=1이고 s1이 s1을 μ„ νƒν•˜λŠ” κ²½μš°λ‚˜, s1이 s2λ₯Ό μ„ νƒν•˜κ³ , s2κ°€ s3λ₯Ό μ„ νƒν•˜κ³ ,..., sr-1이 sr을 μ„ νƒν•˜κ³ , sr이 s1을 μ„ νƒν•˜λŠ” κ²½μš°μ—λ§Œ ν•œ νŒ€μ΄ 될 수 μžˆλ‹€.

예λ₯Ό λ“€μ–΄, ν•œ λ°˜μ— 7λͺ…μ˜ 학생이 μžˆλ‹€κ³  ν•˜μž. 학생듀을 1λ²ˆλΆ€ν„° 7번으둜 ν‘œν˜„ν•  λ•Œ, μ„ νƒμ˜ κ²°κ³ΌλŠ” λ‹€μŒκ³Ό κ°™λ‹€.

1234567
3 1 3 7 3 4 6

μœ„μ˜ κ²°κ³Όλ₯Ό 톡해 (3)κ³Ό (4, 7, 6)이 νŒ€μ„ 이룰 수 μžˆλ‹€. 1, 2, 5λŠ” μ–΄λŠ νŒ€μ—λ„ μ†ν•˜μ§€ μ•ŠλŠ”λ‹€.

주어진 μ„ νƒμ˜ κ²°κ³Όλ₯Ό 보고 μ–΄λŠ ν”„λ‘œμ νŠΈ νŒ€μ—λ„ μ†ν•˜μ§€ μ•ŠλŠ” ν•™μƒλ“€μ˜ 수λ₯Ό κ³„μ‚°ν•˜λŠ” ν”„λ‘œκ·Έλž¨μ„ μž‘μ„±ν•˜λΌ.

μž…λ ₯

첫째 쀄에 ν…ŒμŠ€νŠΈ μΌ€μ΄μŠ€μ˜ 개수 Tκ°€ 주어진닀. 각 ν…ŒμŠ€νŠΈ μΌ€μ΄μŠ€μ˜ 첫 μ€„μ—λŠ” ν•™μƒμ˜ μˆ˜κ°€ μ •μˆ˜ n (2 ≤ n ≤ 100,000)으둜 μ£Όμ–΄μ§„λ‹€. 각 ν…ŒμŠ€νŠΈ μΌ€μ΄μŠ€μ˜ λ‘˜μ§Έ μ€„μ—λŠ” μ„ νƒλœ ν•™μƒλ“€μ˜ λ²ˆν˜Έκ°€ 주어진닀. (λͺ¨λ“  학생듀은 1λΆ€ν„° nκΉŒμ§€ λ²ˆν˜Έκ°€ λΆ€μ—¬λœλ‹€.)

좜λ ₯

각 ν…ŒμŠ€νŠΈ μΌ€μ΄μŠ€λ§ˆλ‹€ ν•œ 쀄에 좜λ ₯ν•˜κ³ , 각 μ€„μ—λŠ” ν”„λ‘œμ νŠΈ νŒ€μ— μ†ν•˜μ§€ λͺ»ν•œ ν•™μƒλ“€μ˜ 수λ₯Ό λ‚˜νƒ€λ‚΄λ©΄ λœλ‹€.

 

풀이

κΈ°λ³Έ 접근방식은 1차원 dfs

사이클을 μ°Ύμ•„λ‚΄μ„œ 사이클에 μ†ν•œ ν•™μƒλ“€μ˜ 수λ₯Ό 카운트

이후 전체 학생 - 사이클에 μ†ν•œ 학생 수 리턴

#include <iostream>
#include <vector>

using namespace std;

int n, teamed;
vector<int> v;
vector<bool> visit;
vector<bool> finished;

void dfs(int cur) {
    visit[cur] = true;
    int next = v[cur];
    if(!visit[next]) // 아직 λ°©λ¬Έν•˜μ§€ μ•Šμ•˜μ„ 경우
        dfs(next);
    else if(!finished[next]) { // λ°©λ¬Έν–ˆλŠ”λ° νŒ€ μ—†λŠ” 경우
        teamed++; // cur은 νŒ€μ— μ†ν•©λ‹ˆλ‹€
        for(int i=next; i!=cur; i = v[i]) // nextλΆ€ν„° 사이클에 μ†ν•œ 학생 수 카운트
            teamed++;
    }
    finished[cur] = true; // 탐색 μ™„
}

int main() {
    int t;
    cin >> t;
    while(t--) {
        // μž…λ ₯
        cin >> n;
        v.assign(n+1, 0);
        for(int i=1; i<=n; i++)
            cin >> v[i];
        
        // μ—°μ‚°
        teamed = 0;
        visit.assign(n+1, false);
        finished.assign(n+1, false);
        for(int i=1; i<=n; i++) {
            if(!visit[i]) 
                dfs(i);
        }
        
        // 좜λ ₯
        cout << n-teamed << "\n";
    }
    return 0;
}

 

λ°˜μ‘ν˜•