https://www.acmicpc.net/problem/9466
1
7
2 3 4 2 6 7 5
정답 1
#include <iostream>
#include <cstring>
#define MAX 100001
using namespace std;
int graph[MAX];
bool visited[MAX];
bool done[MAX];
int ret;
void dfs(int x) {
visited[x] = true;
if (!visited[graph[x]]) {
dfs(graph[x]); //다음 노드 실행
}
else { //이미 방문했다면
if (!done[graph[x]]) { //다음 노드가 끝나지 않았다면
//cout << "사이클 "<<x<<" ";
for (int i = graph[x]; i != x; i = graph[i]) { //자기 자신으로 돌아올 때까지 반복문
//cout << i<<" ";
ret++;
}
ret++;
//cout << "\n";
}
}
done[x] = true; //모든 확인이 끝났음
//cout << x << " done 처리 \n";
}
int main() {
int t;
cin >> t;
for (int j = 0; j < t; j++) {
int n;
cin >> n;
ret = 0;
memset(graph, 0, sizeof(graph));
memset(visited, false, sizeof(visited));
memset(done, false, sizeof(done));
for (int i = 1; i <= n; i++) {
cin >> graph[i];
}
for (int i = 1; i <= n; i++) {
if (!visited[i]) { //기존의 dfs 실행처리
dfs(i);
}
}
cout << n - ret << "\n";
}
}
https://sw-ko.tistory.com/87
참고
★★★★☆
어찌저찌 풀 수는 있었지만 dfs를 거의 활용하지 않았었다..
path를 추적해서 사이클을 찾는 알고리즘을 짰는데, 많이 비효율적이었던 것 같다.
그래프 문제는 최대한 기존의 dfs를 유지해서 푸는 방법으로 고민해봐야할 것 같다.