알고리즘/백준
BOJ 9466. 텀 프로젝트
아헿헿헿
2022. 7. 10. 06:39
BOJ 9466. 텀 프로젝트
랭크 : 골드3
문제 풀이
그래프를 돌면서 순환이 일어나는 구간을 체크하는 것이 중요하다. 한번 체크하고 나면 두번 다시 체크할 일이 없으므로 부모를 -1로 바꿔주어, 두번 체크하지 않게합니다. 방문한 곳을 두번 체크하지 않기 위해서 union_find를 활용하였는데, 잘 생각해보니 visited 배열에 dfs를 활용하는게 더 깔끔하고 빠르게 풀었을 것 같습니다..
#include <bits/stdc++.h>
#define fastio cin.tie(0)->sync_with_stdio(0)
using namespace std;
int T, N;
int favor[100'001];
int parents[100'001];
int findParents(int i) {
if (parents[i] == i) return i;
else return parents[i] = findParents(parents[i]);
}
void UnionFind(int x, int y) {
x = findParents(x); y = findParents(y);
parents[x] = y;
}
bool isUnion(int x, int y) {
x = findParents(x); y = findParents(y);
return (x == y);
}
int main() {
fastio;
cin >> T;
while (T--) {
int ans = 0;
cin >> N;
for (int i=1; i <= N; i++) {
cin >> favor[i]; parents[i] = i;
};
for (int i=1; i <= N; i++) {
if (parents[i] == -1) continue;
int tmp = i;
vector<int> q;
q.push_back(tmp);
while (parents[favor[tmp]] != -1 && !isUnion(tmp, favor[tmp])) {
UnionFind(tmp, favor[tmp]);
tmp = favor[tmp];
q.push_back(tmp);
}
tmp = favor[tmp];
int j = 0;
while (j < q.size() && q[j] != tmp) {
parents[q[j]] = -1;
j++;
ans++;
};
for (; j< q.size(); j++) {
parents[q[j]] = -1;
};
};
cout << ans << endl;
}
}
알고리즘 |
시간복잡도 |
공간복잡도 |
---|---|---|
union_find, 그래프 | $O(N)$ | $O(N)$ |
```