[백준 자바] 1260 DFS와 BFS
2023. 12. 12. 19:44
728x90
배웠던 BFS와 DFS 활용하는 문제~~~
출력 형태를 맞추느라고 StringBuffer 사용했다.
- 첫번째 풀이 (그냥 주르륵 나열/ Stack, Queue 사용)
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.*;
// DFS와 BFS
public class Main {
public static void main(String[] args) throws IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
// 첫째 줄 정점의 개수 N, 간선의 개수 M, 탐색 시작할 번호 V
String[] inputs = br.readLine().split(" ");
int N = Integer.parseInt(inputs[0]); //방문지점 개수
int M = Integer.parseInt(inputs[1]); //연결다리 개수
int V = Integer.parseInt(inputs[2]); // 시작번호
int[][] map = new int[N+1][N+1]; //방문지점과 각 지점의 연결성을 표시하는 맵
// 다음 M개의 줄에는 간선이 연결하는 두 정점의 번호.
for(int i=0; i<M; i++) {
String[] connects = br.readLine().split(" ");
int start = Integer.parseInt(connects[0]);
int last = Integer.parseInt(connects[1]);
map[start][last] = 1;
map[last][start] = 1;
} // 맵 완성
// 첫째줄에는 DFS 결과
// 1. Stack
// 2. List 방문한 곳 저장
// 3. 방문 여부 저장 boolean
Stack<Integer> toVisit = new Stack<>();
StringBuffer sb = new StringBuffer();
boolean[] visited = new boolean[N+1];
toVisit.push(V); //첫 시작이니 스택에 넣고 시작
while(!toVisit.empty()) {
int num = toVisit.pop(); // 꺼낸 것이 확인할 num
if(visited[num]==true) continue;
sb.append(num+" ");
visited[num] =true;
for(int i=N; i>0; i--) {
if(map[num][i] == 1 && visited[i]== false) {
toVisit.push(i);
}
}
}
System.out.println(sb);
// 둘째줄에는 BFS 결과
Queue<Integer> toVisit2 = new LinkedList<>();
sb.delete(0, sb.length()); //sb초기화
visited = new boolean[N+1]; //visited 초기화
toVisit2.offer(V);
while(!toVisit2.isEmpty()) {
int num2 = toVisit2.poll();
if(visited[num2]==true) continue;
sb.append(num2+" ");
visited[num2] = true;
for(int i=1; i<N+1; i++) {
if(map[num2][i]==1 && visited[i] == false) {
toVisit2.offer(i);
}
}
}
System.out.println(sb);
}
}
- 두번째 풀이 (메서드로 분리, DFS는 재귀함수 사용, BFS는 큐 사용)
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.*;
// DFS와 BFS
public class Main {
static int N;
static int M;
static int V;
static StringBuffer sb;
static boolean[] visited;
static int[][] map;
public static void main(String[] args) throws IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
StringTokenizer st = new StringTokenizer(br.readLine());
N= Integer.parseInt(st.nextToken());
M= Integer.parseInt(st.nextToken());
V= Integer.parseInt(st.nextToken());
map = new int[N+1][N+1];
visited = new boolean[N+1]; //visited 초기화
sb = new StringBuffer();
for(int i=0; i<M; i++) {
st = new StringTokenizer(br.readLine());
int left = Integer.parseInt(st.nextToken());
int right = Integer.parseInt(st.nextToken());
map[left][right]=1;
map[right][left]=1;
}
dfs(V);
System.out.println(sb);
visited = new boolean[N+1]; //visited 초기화
sb.delete(0, sb.length()); //stringBuffer 초기화
bfs(V);
System.out.println(sb);
}
public static void dfs(int V){
visited[V]=true; //들어온 순간 true가 됨.
sb.append(V+" "); //그 값을 sb에 덧붙임
for(int i=1; i<=N; i++) { //V와 연결된 것을 찾는다
if(map[V][i]==1&&!visited[i]){
dfs(i);
}
}
}
public static void bfs(int V){
Queue<Integer> myQueue = new LinkedList<>();
myQueue.offer(V);
while(!myQueue.isEmpty()){
int next = myQueue.poll();
if(visited[next]) continue;
sb.append(next+" ");
visited[next] = true;
for(int i=1; i<=N; i++) {
if(visited[i]) continue;
if (map[next][i] == 1) {
myQueue.offer(i);
}
}
}
}
}
결과는 위에가 첫번째 풀이, 아래가 두번째 풀이...
메서드 나누고, 재귀함수 사용한 것이 훨씬 빠르다!!!!
728x90
'Coding test > 코딩테스트' 카테고리의 다른 글
[백준 자바] 26265번 멘토와 멘티 (1) | 2023.12.26 |
---|---|
[백준 자바] 11650 좌표 정렬하기 (0) | 2023.12.18 |
[백준 자바] 1271 엄청난 부자2 (BigInteger) (0) | 2023.12.12 |
Stack 스택 / 괄호검사 / DFS / 후위표기법 (5) | 2023.12.06 |
연습용 (1) | 2023.12.05 |