오늘도 날로 먹는 문제로 찾아왔다.
코드스테이츠에서 알고리즘을 과정을 진행하고 있어서 진 빠진다.
DFS와 BFS의 기본 코드 작성법을 익히고 차이점을 눈으로 직접 확인하기 좋은 문제이다.
이 문제를 풀려고 시도하는 사람이 DFS와 BFS에 대해 전혀 모를리는 없으므로 기억이 흐릿할 때 보기 좋은 이미지를 첨부하는 것으로 이해를 돕도록 하겠다.
1. dfs
public static void dfs(int v) {
visited[v] = true;
sb.append(String.valueOf(v)).append(" ");
// 현재 정점과 연결된 정점 탐색 -> 해당 정점과 연결된 -> 연결된 -> ...
for (int n : edges.get(v)) {
if ( !visited[n] ) {
dfs(n);
}
}
}
dfs는 연결된 정점을 모조리 탐색한다.
2. dfs
public static void bfs(int v) {
queue.add(v);
checked[v] = true;
while ( !queue.isEmpty() ) {
// 현재 노드 - 큐의 가장 앞에 있는 노드
int current = queue.poll();
sb.append(current).append(" ");
// 1레벨과 연결된 2레벨 탐색, 2레벨과 연결된 3레벨 탐색, .. 반복
for (int n : edges.get(current)) {
if (!checked[n]) {
queue.add(n);
checked[n]=true;
}
}
}
}
bfs는 레벨별 (연결되어 있는 순서)로 탐색한다.
bfs는 헷갈리면 그래프부터 보기보다는 트리를 생각하는 게 쉽다.
1층부터 내려가면서 한 층씩 탐색한다고 생각하면 된다.
3. 정답
import java.util.*;
import java.io.*;
public class Main {
static ArrayList<ArrayList<Integer>> edges = new ArrayList<>();
static LinkedList<Integer> queue = new LinkedList<>();
static StringBuilder sb = new StringBuilder();
public static boolean[] visited;
static boolean[] checked;
public static void main(String[] args) throws IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
StringTokenizer st = new StringTokenizer(br.readLine(), " ");
// 정점 수, 간선 수, 시작점
int V = Integer.parseInt(st.nextToken());
int E = Integer.parseInt(st.nextToken());
int S = Integer.parseInt(st.nextToken());
// 시작점이 1이므로 <=으로 반복문을 돌린다.
for (int i=0; i<=V; i++) {
edges.add(new ArrayList<>());
}
// 무방향(양방향) 그래프이다.
for (int i=0; i<E; i++) {
st = new StringTokenizer(br.readLine(), " ");
int edge1 = Integer.parseInt(st.nextToken());
int edge2 = Integer.parseInt(st.nextToken());
edges.get(edge1).add(edge2);
edges.get(edge2).add(edge1);
}
// 오름차순으로 방문한다
for (int i=0; i<=V; i++) {
Collections.sort(edges.get(i));
}
// 시작 정점이 1이므로 +1
visited = new boolean[V+1];
checked = new boolean[V+1];
dfs(S);
sb.append("\n");
bfs(S);
System.out.println(sb.toString());
}
public static void dfs(int v) {
visited[v] = true;
sb.append(String.valueOf(v)).append(" ");
for (int n : edges.get(v)) {
if ( !visited[n] ) {
dfs(n);
}
}
}
public static void bfs(int v) {
queue.add(v);
checked[v] = true;
while ( !queue.isEmpty() ) {
// 현재 노드 - 큐의 가장 앞에 있는 노드
int current = queue.poll();
sb.append(current).append(" ");
for (int n : edges.get(current)) {
if (!checked[n]) {
queue.add(n);
checked[n]=true;
}
}
}
}
}
'CS ﹒ Algorithm > Baekjoon' 카테고리의 다른 글
Java 백준 문제풀이 (34) 2609: 최대공약수와 최소공배수 (0) | 2022.08.02 |
---|---|
Java 백준 문제풀이 (33) 2667: 단지 번호 붙이기 (0) | 2022.08.01 |
Java 백준 문제풀이 (31) 2606: 바이러스 (0) | 2022.07.30 |
Java 백준 문제풀이 (30) 11725: 트리의 부모 찾기 (0) | 2022.07.29 |
Java 백준 문제풀이 (29) 2444: 알고리즘 수업 - 너비 우선 탐색 1 (0) | 2022.07.28 |