[문제]
https://www.acmicpc.net/problem/9466
[풀이]
사이클을 이룰 경우 해당 팀이 만들어진다. 사이클을 이뤄서 팀에 포함된 학생들의 수를 센 후 전체 학생 수에서 빼주면 된다.
여기서 사용된 isFinished 배열은 사이클을 이룰 경우 이미 방문한 정점도 다시 방문할 수 있기 때문에 다시는 방문할 필요가 없는 정점임을 표시해주기 위해 필요하다. (예제에서 4 -> 7 -> 6 -> 4 와 같이)
방문하지 않은 정점들에 대해서만 dfs를 돌려서 최적화해주어야 시간초과가 발생하지 않는다.
[코드]
#include <iostream>
#include <algorithm>
#include <vector>
#include <queue>
#include <cstring>
#define INF 987654321
using namespace std;
int t;
bool visited[100001];
bool isFinished[100001];
int graph[100001];
int cnt;
void dfs(int i){
visited[i] = true;
int next = graph[i];
if(!visited[next]){
dfs(next);
}
else if(!isFinished[next]){ //사이클을 이룸
for(int j=next; j!=i; j=graph[j]){
cnt++;
}
cnt++;
}
isFinished[i] = true;
}
int main(){
ios::sync_with_stdio(false);
cin.tie(0);
cout.tie(0);
cin >> t;
while(t--){
int n;
cin >> n;
for(int i=1; i<=n; i++){
cin >> graph[i];
}
for(int i=1; i<=n; i++){
if(!visited[i]){
dfs(i);
}
}
cout << n-cnt << "\n";
cnt = 0;
memset(visited, false, sizeof(visited));
memset(isFinished, false, sizeof(isFinished));
}
}
'알고리즘 공부 및 문제 풀이 > 백준(BOJ)' 카테고리의 다른 글
[boj] 백준 4386 별자리 만들기 (c++) - 최소신장트리 MST (0) | 2022.10.24 |
---|---|
[boj] 백준 2533 사회망 서비스 (c++) - 트리, dp (0) | 2022.10.23 |
[boj] 백준 16235 나무 재테크 (c++) - 시뮬레이션 (0) | 2022.10.18 |
[boj] 백준 2623 음악프로그램 (c++) - 위상정렬 (0) | 2022.10.17 |
[boj] 백준 11779 최소비용 구하기 2 (c++) - 다익스트라 (0) | 2022.10.17 |