[Java] 백준 1260번 [DFS와 BFS] 자바
백준 1260번
https://www.acmicpc.net/problem/1260
문제
그래프를 DFS로 탐색한 결과와 BFS로 탐색한 결과를 출력하는 프로그램을 작성하시오. 단, 방문할 수 있는 정점이 여러 개인 경우에는 정점 번호가 작은 것을 먼저 방문하고, 더 이상 방문할 수 있는 점이 없는 경우 종료한다. 정점 번호는 1번부터 N번까지이다.
입력
첫째 줄에 정점의 개수 N(1 ≤ N ≤ 1,000), 간선의 개수 M(1 ≤ M ≤ 10,000), 탐색을 시작할 정점의 번호 V가 주어진다. 다음 M개의 줄에는 간선이 연결하는 두 정점의 번호가 주어진다. 어떤 두 정점 사이에 여러 개의 간선이 있을 수 있다. 입력으로 주어지는 간선은 양방향이다.
생각하기
DFS와 BFS의 개념을 다지기 위한 기초 문제이다.
나도 공부를 하면서 워낙 힘들었던 터라 개념설명은 힘들 것 같고..
그냥 정리만 하는걸로..
일단 DFS는 재귀나 stack을 주로 사용하고
BFS는 보통 LinkedList나 Queue를 사용한다.
여기서 내가 사용한 방법은 DFS는 재귀, BFS는 Queue를 사용했다.
DFS를 가장 쉽게 설명할 수 있는 말은 '한놈만 팬다' 이고
BFS를 가장 쉽게 설명할 수 있는 말은 '이놈패다가 저놈패는것(?)'이다.
이게 맞나?
본격적으로 문제를 풀이해보자면
방문한 노드를 기록할 수 있는 배열이 하나 필요하고,
간선을 기록하는 배열이 필요하다
나는 이 2개를 Visited_arr
과 Edge_arr
로 만들었다.
Visited_arr
은 방문의 여부만 따지면 되기 때문에 true/false로 기록했다. (boolean형)
Edge_arr
은 당연히 int형
아, 여기서 또 생각해야 할 점이 Visited_arr
의 사이즈가 1001로 되어있는데, 이는 노드(정점)의 숫자는 1부터 시작하지만
배열은 0부터 시작하기 때문에 사이즈를 맞추기위해서 1을 + 한 값으로 배열을 생성하는 것이다.
1000의 의미는 당연히 정점의 최대 갯수!
기본적인 배열에 담는 부분은 뛰어넘기로 하고,
DFS먼저 보자
DFS
먼저 시작은 첫번째 출발 노드를 알려줬으니 V
를 이용해서 시작한다 ->DFS(V)
DFS가 시작되면 해당 노드 자체가 방문을 했다는 의미가 되니까
Visited_arr[start]
에 해당하는 값을 true로 바꿔준다
참고로 boolean형 배열을 처음에 만들면 모두 false값으로 초기화 되어있다.
count
는 재귀함수를 호출하면서 밑에 있는 반복문을 이용하게 되는데
최대한 반복횟수를 줄일 수 있도록 마지막에 DFS가 실행됬을 때, count
값과 노드의 갯수(N
)가 같을 경우 곧바로 return을 하여 DFS를 종료시키도록 만들어줬다.
이제 아래에 있는 반복문을 보자.
for문에서 i
값을 1부터 증가시켜서 노드최대값 N
까지 증가시키며 반복한다.
이렇게 되면 start
방향에서 출발해서 다른 i
값 노드로 가는 간선이 있는지 모두 체크하게 된다.
여기서 한놈만 패는 스타일이 나오는 것이다.
start
값이 정해지면 해당 start
값에서 출발하는 간선이 있는지 계속 찾는다.
그리고 간선을 찾았을 경우 i
값을 DFS(i)
로 해서 i
값이 start
가 되게 만들어 DFS를 실행시키는 것이다.
이 과정을 계속 반복하면서 연결되는 간선을 타고 타고, 넘어가며 모든 노드를 방문해서
Visited_arr
배열이 모두 true가 되는 순간(Visited-arr[0]
은 false) DFS는 끝나게 된다.
BFS
이제 여러 놈을 한번 동시에 패보자.
위에서 말했듯 BFS는 Queue를 이용한다.
Queue가 비었으면 모든 노드를 방문한 것이 되는 것이다.
DFS와 똑같이 BFS(V)
로 시작해서
시작되는 start
값을 먼저 que
에 집어 넣는다.
이해 start
값을 다시 que
에서 빼낸 값으로 바꿔주고
이 값을 시작점으로 i
값을 증가시키며 노드를 찾는다
여기서 차이점이 드러나는데
DFS 였으면 i
값이 start
로 바뀌어 다음 노드로 넘어갔을 테지만
BFS는 start
값은 그대로 두고 i
값을 증가시켜서 계속 연결된 간선을 찾는다는 것이다.
여기서 연결되 있는 간선을 보고 노드 값을 찾아서 해당 노드값을 que
에 넣는다
(첫번째 테스트케이스 기준)
처음 시작 하는 노드 1을 기준으로 보면 2 3 4와 연결되어 있으니
i
값을 증가하면서 2 3 4 값을 que
에 넣는다고 생각하면 된다.
해당 과정을 반복하고,que
가 비어있을 때 까지 이 과정을 반복한다.
이렇게 되면 BFS가 종료된다.
TMI
어려운 것 같으면서도 쉬운것 같기도 하다
사실 어렵다기보다는 진짜 복잡한 것 같다..
이 문제를 풀려고 재귀관련된 문제와 공부를 다시 하고왔다ㅠㅠ
이렇게 성장하는거 아니겠나 싶다
머리가 조금만 더 좋았으면 좋았을텐데!!
난 왜 머리가 나쁠까!!
코드
import java.util.*;
import java.io.*;
public class Main {
static int Edge_arr[][];
static boolean Visited_arr[];
static int N;
static int M;
static int V;
static int count;
static Queue<Integer> que = new LinkedList<>();
public static void BFS(int start) {
que.offer(start);
Visited_arr[start] = true;
System.out.print(start + " ");
while( !que.isEmpty() ) {
start = que.poll();
for(int i=1; i<=N; i++) {
if(Edge_arr[start][i] == 1 && Visited_arr[i] == false) {
que.offer(i);
Visited_arr[i] = true;
System.out.print(i + " ");
}
}
}
}
public static void DFS(int start) {
Visited_arr[start] = true;
System.out.print(start + " ");
if(count == N) {
return;
}
count ++;
for(int i=1; i<=N; i++) {
if(Edge_arr[start][i] == 1 && Visited_arr[i] == false) {
DFS(i);
}
}
}
public static void main(String[] args) throws Exception {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
StringTokenizer st = null;
st = new StringTokenizer(br.readLine());
N = Integer.parseInt(st.nextToken());
M = Integer.parseInt(st.nextToken());
V = Integer.parseInt(st.nextToken());
Edge_arr = new int[1001][1001];
Visited_arr = new boolean[1001];
for(int i=0; i<M; i++) {
st = new StringTokenizer(br.readLine());
int x = Integer.parseInt(st.nextToken());
int y = Integer.parseInt(st.nextToken());
Edge_arr[x][y] = Edge_arr[y][x] = 1;
}
DFS(V);
System.out.println();
Visited_arr = new boolean[1001];
BFS(V);
}
}
Author And Source
이 문제에 관하여([Java] 백준 1260번 [DFS와 BFS] 자바), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다
https://velog.io/@lifeisbeautiful/Java-백준-1260번-DFS와-BFS-자바
저자 귀속: 원작자 정보가 원작자 URL에 포함되어 있으며 저작권은 원작자 소유입니다.
우수한 개발자 콘텐츠 발견에 전념
(Collection and Share based on the CC Protocol.)
import java.util.*;
import java.io.*;
public class Main {
static int Edge_arr[][];
static boolean Visited_arr[];
static int N;
static int M;
static int V;
static int count;
static Queue<Integer> que = new LinkedList<>();
public static void BFS(int start) {
que.offer(start);
Visited_arr[start] = true;
System.out.print(start + " ");
while( !que.isEmpty() ) {
start = que.poll();
for(int i=1; i<=N; i++) {
if(Edge_arr[start][i] == 1 && Visited_arr[i] == false) {
que.offer(i);
Visited_arr[i] = true;
System.out.print(i + " ");
}
}
}
}
public static void DFS(int start) {
Visited_arr[start] = true;
System.out.print(start + " ");
if(count == N) {
return;
}
count ++;
for(int i=1; i<=N; i++) {
if(Edge_arr[start][i] == 1 && Visited_arr[i] == false) {
DFS(i);
}
}
}
public static void main(String[] args) throws Exception {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
StringTokenizer st = null;
st = new StringTokenizer(br.readLine());
N = Integer.parseInt(st.nextToken());
M = Integer.parseInt(st.nextToken());
V = Integer.parseInt(st.nextToken());
Edge_arr = new int[1001][1001];
Visited_arr = new boolean[1001];
for(int i=0; i<M; i++) {
st = new StringTokenizer(br.readLine());
int x = Integer.parseInt(st.nextToken());
int y = Integer.parseInt(st.nextToken());
Edge_arr[x][y] = Edge_arr[y][x] = 1;
}
DFS(V);
System.out.println();
Visited_arr = new boolean[1001];
BFS(V);
}
}
Author And Source
이 문제에 관하여([Java] 백준 1260번 [DFS와 BFS] 자바), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://velog.io/@lifeisbeautiful/Java-백준-1260번-DFS와-BFS-자바저자 귀속: 원작자 정보가 원작자 URL에 포함되어 있으며 저작권은 원작자 소유입니다.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)