문제 1260번
: 그래프를 DFS로 탐색한 결과와 BFS로 탐색한 결과를 출력하는 프로그램
: 방문할 수 있는 정점이 여러 개인 경우 정점 번호가 작은 것부터 방문
: 더 이상 방문할 수 있는 점이 없을 때 종료
: 정점 번호는 1 ~ N
[입력]
: 첫째 줄에는 정점 수 N, 간선 개수 M, 탐색을 시작할 정점 번호 V
: 둘째 줄부터 간선이 연결하는 두 정점의 번호
(정점 사이에 여러 개의 간선이 있을 수 있고 입력으로 주어지는 간선은 양방향)
[출력]
: V부터 방문된 점을 순서대로 출력
[설명]
- DFS
![](https://blog.kakaocdn.net/dn/lne2x/btstVfA2H6L/2GpSGfMHw7953b3Ty5KKm0/img.gif)
현재 정점에서 갈 수 있는 점들까지 들어가면서 탐색
Stack 혹은 재귀함수로 구현
- 경로를 탐색할 때 한 방향으로 갈 수 있을 때까지 계속 가다가
더 이상 갈 수 없게되면 다른 방향으로 다시 탐색 진행 - 모든 노드를 방문하는 경우에 사용
- BFS
![](https://blog.kakaocdn.net/dn/NQXSb/btstXx9eF2H/FTGULzL5CxRM8CbQYiKI1k/img.gif)
현재 정점에 연결된 가까운 점들부터 탐색
Queue를 사용해서 구현
[코드]
import java.io.*;
import java.util.*;
public class Main{
static int[][] arr;
static boolean[] visit;
static int x, y, N;
static Queue<Integer> q = new LinkedList<>();
public static void main(String[] args)throws IOException{
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
StringTokenizer st;
st= new StringTokenizer(br.readLine());
N = Integer.parseInt(st.nextToken());
int M = Integer.parseInt(st.nextToken());
int V = Integer.parseInt(st.nextToken());
arr = new int[N+1][N+1];
visit = new boolean[N+1];
for(int i =0; i<M; i++){
st= new StringTokenizer(br.readLine());
x = Integer.parseInt(st.nextToken());
y = Integer.parseInt(st.nextToken());
arr[x][y] = arr[y][x] = 1;
}
DFS(V);
System.out.println();
visit = new boolean[N + 1];
BFS(V);
}
public static void DFS(int node){
visit[node]=true;
System.out.print(node + " ");
for(int i =1; i< N+1; i++){
if(arr[node][i]==1 && visit[i] == false){
DFS(i);
}
}
}
public static void BFS(int node){
q.add(node);
visit[node]=true;
while(!q.isEmpty()) {
node= q.poll();
System.out.print(node + " ");
for(int i = 1; i<N+1; i++){
if(arr[node][i] == 1 && visit[i]==false) {
q.add(i);
visit[i] = true;
}
}
}
}
}
[해설]
: static int[][] arr; 2차원 배열 설정
static boolean[] visit; 방문기록 설정
static int x, y; 둘째줄부터 입력되는 x, y
static int N; 첫째줄 입력 N (main, DFS, BFS에 모두 쓸거라 앞으로 뺌)
static Queue<Integer> q = new LinkedList<>(); BFS에서 사용
: st = new StringTokenizer(br.readLine()); 한 줄 입력보기
N = Integer.parseInt(br.readLine()); 노드 개수 (첫째 줄 입력)
int M = Integer.parseInt(st.nextToken()); 연결선 개수 (첫째 줄 입력)
int V = Integer.parseInt(st.nextToken()); 시작노드 (첫째 줄 입력)
: arr = new int[n+1][n+1]; 배열 1부터 보려고 + 1 하기
visit = new boolean[n+1]; 배열 1부터 보려고 +1 하기
: for(int i=0; i<M; i++) { 쌍을 이루는 개수만큼만 계산
st = new StringTokenizer(br.readLine()); 단어 끊어 읽기
int x = Integer.parseInt(st.nextToken()); 연결 노드 (둘째 줄부터)
int y = Integer.parseInt(st.nextToken()); 연결 노드 (둘째 줄부터)
arr[x][y] = arr[y][x] = 1; 입력받은 값들 1로 처리 (arr[1][2] = arr[2][1])
}
: DFS(V); dfs에 V 넣고 시작 (시작 노드 고정하고 계산)
System.out.println();
: visit = new boolean[N+1]; bfs에서도 visit 쓸거라 새롭게 지정
안그러면 dfs에서 사용된 값들이 누적된다
BFS(V); bfs에 V 넣고 시작 (시작 노드 고정하고 계산)
: public static void DFS(int node) { node 현재 비교값
visit[node] = true; 현재의 노드를 방문 처리 ( V = node 로 초기값 고정)
System.out.print(node+ " "); 노드로 지정될 때마다 출력
for(int i=1; i<N+1; i++) {
if(arr[node][i] == 1 && visit[i] == false) { node와 연결됐지만 방문 기록은 false
DFS(i, count+1); 현 node는 V이다
} 방문기록이 없는 다른 노드들로 새롭게 갱신
}
}
: public static void BFS(int node) { node 현재 비교값
q.add(node); 노드들 큐에 삽입
visit[node] = true; 현재의 노드를 방문 처리 ( V = node 로 초기값 고정)
while(!q.isEmpty()) {
node = q.poll(); 큐가 빌 때까지 큐에서 뺀 것들 node에 저장
큐에 초기값 node = V 넣었으니까 바로 빼고 밑에 코드 실행
밑에서 q.add(i) 로 넘어오는 노드들 다 빼서 node에 저장
System.out.print(node+ " "); 노드 출력
for(int i=1; i<N+1; i++) {
if(arr[node][i] == 1 && visit[i] == false) { node 연결O, 방문기록 false
q.add(i); 해당 i 큐에 넣기
} visit[i] = true; 방문처리
}
}
[문제 과정]
![](https://blog.kakaocdn.net/dn/coqxCP/btstZaso1wT/m6HoA3yATKaBxEde3qK8kk/img.png)
총 노드 | 5 |
시작 노드 | 3 |
연결 노드 | 5 - 4 5 - 2 1 - 2 3 - 4 3 - 1 |
DFS | ||||
방문처리 완료 | 다음 경로확인 | DFS | 출력 | |
1 단계 | visit[3] | arr[3][1] | DFS(3) | 3 |
2 단계 | visit[1] | arr[1][2] | DFS(1) | 1 |
3 단계 | visit[2] | arr[2][5] | DFS(2) | 2 |
4 단계 | visit[5] | arr[5][4] | DFS(5) | 5 |
5 단계 | visit[4] | - | DFS(4) | 4 |
BFS | ||||
계산 | q.add | q.poll | 방문완료 / 출력 | |
1 단계 | 초기값 3부터 시작 | 3 | 3 | 3 |
2 단계 | 3이랑 연결된 노드 찾기 | 1, 4 | 1, 4 | 1, 4 |
3 단계 | 1이랑 연결된 노드 찾기 | 2 | 2 | 2 |
4 단계 | 4랑 연결된 노드 찾기 | 5 | 5 | 5 |
이제 풀어보러 갈께요 :)
![](https://blog.kakaocdn.net/dn/dG1AXq/btstX40caRi/Kva4iRCK4ciqsXRsS3QUuK/img.jpg)
1260번: DFS와 BFS
첫째 줄에 정점의 개수 N(1 ≤ N ≤ 1,000), 간선의 개수 M(1 ≤ M ≤ 10,000), 탐색을 시작할 정점의 번호 V가 주어진다. 다음 M개의 줄에는 간선이 연결하는 두 정점의 번호가 주어진다. 어떤 두 정점 사
www.acmicpc.net
* 독학으로 익히는 코딩이라 틀린 것이 있을 수 있습니다. 오류가 있다면 댓글을 통해 알려주세요. 감사합니다. *
'Baekjoon > [5] DFS & BFS' 카테고리의 다른 글
[백준] 11724번 연결 요소의 개 JAVA (자바) 풀이 (0) | 2023.09.16 |
---|---|
[백준] 4963번 섬의 개수 JAVA (자바) 풀이 (0) | 2023.09.15 |
[백준] 2644번 촌수계산 JAVA (자바) 풀이 (0) | 2023.09.12 |
[백준] 1012번 유기농 배추 JAVA (자바) 풀이 (0) | 2023.09.11 |
[백준] 2606번 바이러스 JAVA (자바) 풀이 (0) | 2023.09.11 |