Closed yeongleej closed 3 hours ago
dfs(int x) 동작
isfinish로 해당 노드 dfs 종료 처리
private static void dfs(int x) {
visited[x] = ++order; // 현재 지점 몇번째로 방문했는지 체크
int nxt = choose[x]; // 현재 학생이 선택한 학생
if (visited[nxt]==0) { // 선택된 학생을 방문하지 않았으면 dfs진행
dfs(nxt);
} else if (!isFinish[nxt]) { // 방문은 했는데 dfs가 끝나지 않았으면 사이클
cnt += visited[x] - visited[nxt] + 1;
}
isFinish[x] = true;
}
해당 노드에서 방문한 노드를 재 방문하는 경우 사이클이 발생
// 사이클이 발생하는지 재귀로 탐색
private static void recurse(int cur) {
// 방문 처리
visited[cur] = true;
int next = arr[cur]; // 현재 학생이 함께하고 싶은 학생
// 다음 학생이 방문 처리가 되어있지 않다면
if (!visited[next]) {
// 다음 학생 탐색
recurse(next);
// 방문한 학생인데 사이클이 아직 발생하지 않은 학생일 경우 } else if (!isCycle[next]) { // 현재 학생이 이루는 모든 사이클의 수를 계산 cnt++; while (next != cur) { cnt++; next = arr[next]; } } // 현재 재귀에 있는 모든 학생 사이클 체크 // 다른 재귀에서 해당 학생들은 사이클이 발생할 수 없으므로 isCycle[cur] = true; }
=> 최대 O(N log N)으로 생각해보기
visited[]
: 전체 방문 확인 여부finished[]
: 사이클 확인 여부int next = g[now];
// 아직 방문하지 않음 -> 사이클 발생 X
if(!visited[next]) {
dfs(next);
}
// 사이클 발생
else {
// 사이클 내부 방문
while(!finished[next]) {
finished[next] = true;
next = g[next];
cnt--; // 사이클 내부 노드는 팀에 속하는 노드
}
}
// now 노드는 종료 처리
finished[now] = true;
int[] arr
: 함께 하고 싶은 학생 번호 저장boolean[] check
: 해당 학생을 확인했는지 저장boolean[] v
: dfs를 수행할 때, 사이클이 발생했는지 확인하는 용도로 사용static void dfs(int start, int current) {
if(check[current]) return;
// 사이클이 발생한 경우
if(v[current]) {
check[current] = true;
cnt += 1;
}
v[current] = true;
dfs(start, arr[current]);
check[current] = true; // 확인 표시
v[current] = false; // 원상복구
}
DFS 함수 만들 때, 조건 설정 & 상태 변화 잘 하기
O(N log N)
students[i] == i
N-cycleCnt
)static void dfs (int n){
if(visited[n]){ // 이미 방문한 노드를 방문한 경우
cycle[n] = true; // 사이클 발생 의미
cycleCnt++;
} else{
visited[n] = true; // 방문처리
}
if(!cycle[students[n]]){ // 다음 학생이 팀 결성을 아직 못했을 경우
dfs(students[n]); // 다시 탐색 시작
}
visited[n] = false;
cycle[n] = true;
}
}
3 초
2 ≤ n ≤ 100,000
DFS 로 풀이할 경우 O(n+m)
> O(n)
으로 풀이가능boolean[] visited
: 방문 유무boolean[] isFinished
: 재방문 + 사이클 시도 완료 유무boolean[] isGrouping
: 팀 프로젝트 가능 유무isFinished
작업 완료 처리isGrouping
에서 프로젝트 팀에 속하지 못한 학생들 카운팅(false
)