https://school.programmers.co.kr/learn/courses/30/lessons/67260
BFS 응용
복잡해보이지만 사실 단순 BFS로 풀 수 있다.
문제의 핵심은 선 방문 조건이 있는 그래프의 모든 정점을 갈 수 있는가
를
묻는 것이다.
예시로 한 번 살펴보자.
BFS, Step1.
우선 0번 부터 탐색한다.
BFS를 통해 1,3,7번을 탐색할 수 있다.
하지만 1,7의 경우, 선행 방문 정점이 존재한다.
따라서 3번만 큐에 넣어준다.
BFS, Step2.
이제 큐에 있는 3번 정점을 탐색해주자.
3번에서는 한 번도 방문하지 않은 6번 정점을 방문 할 수 있다.
BFS, Step3.
이제 6번 정점을 탐색한다.
6번 정점을 방문하게 된다면, 7번 정점을 방문할 수 있는 조건을 만족한다.
여기서 처리를 잘 해야한다.
7번 정점은 앞서 0번에서 갈 수 있는 지점이 었다.
하지만 0번은 BFS에서 큐를 통해 이미 탐색한 지점이다.
어떻게 7번 정점을 BFS 큐에 넣을 수 있을까.
무작정 집어 넣는다면, 뜬금 없는 지점에서부터 다시 탐색하는 경우가 발생한다.
따라서 방문하고자 하는 7번 정점을 기준으로, 인접한 정점 중, 이미 방문한 정점이 있다면, 큐에 넣어주면 된다.
BFS, Step4....
앞으로의 과정은 1~3과정을 반복하면 된다.
요약
1. BFS를 통해 탐색한다.
2. Map을 통해 선행 정점을 기록한다.
3. 방문 체크를 할 2개의 배열을 별도로 생성한다.
- BFS를 통해 방문한 지점인지 확인
- 현재 탐색할 수 있는 지점인지 확인
import java.util.*;
class Solution {
List<Integer>[] list;
boolean[] canVisit;
Map<Integer, Integer> map = new HashMap<>();
public boolean solution(int n, int[][] path, int[][] order) {
list = new List[n];
canVisit = new boolean[n];
Arrays.fill(canVisit, true);
for (int data[] : order) {
map.put(data[0], data[1]);
canVisit[data[1]] = false;
}
for (int i = 0; i < n; ++i)
list[i] = new ArrayList<>();
for (int data[] : path) {
list[data[0]].add(data[1]);
list[data[1]].add(data[0]);
}
Queue<Integer> q = new ArrayDeque<>();
boolean[] visit = new boolean[n];
visit[0] = true;
q.add(0);
int count = 1;
while (!q.isEmpty()) {
int cur = q.poll();
for (int next : list[cur]) {
// 갈 수 있으며, 방문한 적이 없다면 진행
if (canVisit[next] && !visit[next]) {
visit[next] = true;
q.add(next);
count++;
}
}
// 현재 방을 방문함으로써, 새롭게 열리는 방이 있는 경우
if (map.containsKey(cur)) {
int next = map.get(cur);
canVisit[next] = true;
for (int check : list[next]) {
if (visit[check]) {
visit[next] = true;
q.add(next);
count++;
break;
}
}
}
}
return count == n ? true : false;
}
}