Notice
Recent Posts
Recent Comments
Link
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | ||||
4 | 5 | 6 | 7 | 8 | 9 | 10 |
11 | 12 | 13 | 14 | 15 | 16 | 17 |
18 | 19 | 20 | 21 | 22 | 23 | 24 |
25 | 26 | 27 | 28 | 29 | 30 | 31 |
Tags
- 백준11724
- 백준1253
- 백준17298
- 백준13023
- 백준
- 백준11720
- 정렬알고리즘
- 백준1546
- 백준1260
- 백준2023
- 백준2751
- 백준11399
- 백준10998
- 구간합
- 자바
- 백준_구간합구하기
- stack
- 백준1427
- 백준11003
- 백준2018
- 버블소트
- 백준1940
- 백준_11659
- Java
- 백준1517
- 백준1377
- 백준1874
- 백준11286
- 백준12891
- 백준2750
Archives
- Today
- Total
HOONDOC
[백준]2750 수 정렬하기 2 - 자바/Java 본문
13023번: ABCDE
🌱풀이
알고리즘
- 각 사람을 기준으로 DFS를 돌며, 깊이가 5에 도달하는 경우가 있는지를 확인한다.
- 확인을 위해 arrive라는 boolean형 변수를 선언하여 종료 조건에서 true로 바꾼다.
- 인접 리스트를 선언하여 무방향 그래프를 표현한다.
- 특이하게도 visited 배열을 true로 바꿨다가 해당 에지의 탐색이 종료되면 false로 초기화한다. 이는 0번 사람을 기준으로는 깊이 5가 나오지 않을지라도 4번 사람을 기준으로는 깊이 5가 나올 수 있기 때문이다. 예제 2번에서 확인할 수 있다.
- 단순하게 에지를 한번씩 탐색하는게 목적이라면 false로 바꿔주지 않아도 된다. 하지만 이번 문제처럼 각 에지별 깊이를 알고 싶거나 하는 등의 더 많은 방문을 필요로 하는 경우에는 초기화 과정이 필요하다.
메모리 : 39528KB, 시간 : 400ms
import java.util.ArrayList;
import java.util.Scanner;
public class Main {
//깊이가 5 이상인 DFS을 찾는 문제다.
static boolean visited[];
static ArrayList<Integer>[] A;
static boolean arrive;
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
arrive = false;
int N = sc.nextInt(); //사람의 수
int M = sc.nextInt(); //관계의 수
A = new ArrayList[N];
visited = new boolean[N];
for(int i = 0; i<N; i++) A[i] = new ArrayList<Integer>();
for(int i = 0; i<M; i++) {
int s = sc.nextInt();
int e = sc.nextInt();
A[s].add(e);
A[e].add(s);
}
for(int i = 0; i<N; i++) {
DFS(i, 1); //i는 사람의 번호, 1은 최초 깊이
if(arrive) break;
}
if(arrive) System.out.print("1");
else System.out.print("0");
}
static void DFS(int now, int depth) {
if(depth == 5 || arrive) {
arrive = true;
return;
}
visited[now] = true;
for(int i : A[now]) {
if(visited[i]) continue;
DFS(i, depth+1);
}
visited[now] = false;
}
}
🪴코드 리뷰
🌿메모리 : 38512KB, 시간 : 512ms
DFS 재귀 함수가 true로 반환되며 종료되려면 인접 리스트에 접근하고 난 뒤에야 가능하므로, 연산량이 증가한 것으로 보인다. 이는 DFS 메소드 내부에 인접 리스트를 꺼내는 반복문에 종료 확인 조건이 또 존재하기 때문이다.
💡 풀이자 : dyffh1031
import java.util.*;
public class Main {
static boolean[] visited;
static ArrayList<Integer>[] adj;
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
int n = sc.nextInt();
visited = new boolean[n];
int m = sc.nextInt();
adj = new ArrayList[n];
for(int i = 0; i < n; i++) adj[i] = new ArrayList<>();
for(int i = 0; i < m; i++) {
int num1 = sc.nextInt();
int num2 = sc.nextInt();
adj[num1].add(num2);
adj[num2].add(num1);
}
for (int i = 0; i < n; i++) {
if(dfs(i,1)) {
System.out.println(1);
return;
}
}
System.out.println(0);
}
private static boolean dfs(int curr, int depth) {
if(depth == 5) {
return true;
}
visited[curr] = true;
for(int next : adj[curr]) {
if(visited[next]) continue;
if(dfs(next, depth+1)) return true;
}
visited[curr] = false;
return false;
}
}
🌿메모리 : 14996KB, 시간 : 228ms
BufferedReader를 사용해서 시간이 줄은 것으로 보인다. 이 외에도 인접 리스트를 사용자 정의 자료구조 Node로 선언한 것이 특징이다. 근데 이건 인접 리스트라기보다는 인접 배열 + 사용자 정의 클래스다.
💡 풀이자 : pjys211
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.StringTokenizer;
public class Main{
public static int N, M;
public static Node[] nodeList;
public static boolean[] visited;
public static boolean possible;
public static class Node{
int num;
Node node;
public Node(int num, Node node){
this.num = num;
this.node = node;
}
}
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());
nodeList = new Node[N];
visited = new boolean[N];
possible = false;
for (int i = 0; i < M; i++){
st = new StringTokenizer(br.readLine());
int from = Integer.parseInt(st.nextToken());
int to = Integer.parseInt(st.nextToken());
nodeList[from] = new Node(to,nodeList[from]);
nodeList[to] = new Node(from,nodeList[to]);
}
for (int num = 0; num < N; num++){
visited[num] = true;
DFS(num,1);
visited[num] = false;
}
if (possible){
System.out.println(1);
}else{
System.out.println(0);
}
}
public static void DFS(int num, int count){
if(count == 5){
possible = true;
return;
}
if(possible){
return;
}
for (Node temp = nodeList[num]; temp != null; temp = temp.node){
if(visited[temp.num]) continue;
count++;
visited[temp.num] = true;
DFS(temp.num, count);
count--;
visited[temp.num] = false;
}
}
}
🌿메모리 : 16908KB, 시간 : 200ms
이 사람은 인접 리스트가 불필요하게 선언되지 않도록 존재하는 친구들을 기준으로만 선언했다. if(arr[a]==null) 이 조건에서 알 수 있다.
💡 풀이자 : kws04254
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.*;
public class Main {
public static void main(String[] args) throws IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
StringTokenizer st = new StringTokenizer(br.readLine());
int N = Integer.parseInt(st.nextToken());
int M = Integer.parseInt(st.nextToken());
List<Integer> [] arr = new ArrayList[N];
for(int i=0; i<M;i++) {
st = new StringTokenizer(br.readLine());
int a = Integer.parseInt(st.nextToken());
int b = Integer.parseInt(st.nextToken());
if(arr[a]==null) {
arr[a] = new ArrayList<Integer>();
}
if(arr[b]==null) {
arr[b] = new ArrayList<Integer>();
}
arr[a].add(b);
arr[b].add(a);
}
boolean check[];
for(int i=0; i<N;i++) {
check = new boolean[N];
check[i] =true;
if(dfs(arr, check, 0, i)) {
System.out.println(1);
return;
}
}
System.out.println(0);
}
public static boolean dfs(List<Integer> [] arr, boolean[] check, int num, int cur) {
if(num==4) {
return true;
}
if(arr[cur]==null) return false;
for(int i=0; i< arr[cur].size();i++) {
int next = arr[cur].get(i);
if(check[next]) continue;
check[next] = true;
if(dfs(arr,check,num+1,next)) return true;
check[next] = false;
}
return false;
}
}
Conclusion
- DFS에서 방문 배열을 초기화 하는 경우의 수를 생각해볼 수 있었다.
'문제 풀이 > BAEKJOON' 카테고리의 다른 글
[백준]1260 DFS와 BFS - 자바/Java (0) | 2023.01.08 |
---|---|
[백준]2023 신기한 소수 - 자바/Java (0) | 2023.01.06 |
[백준]11724 연결 요소의 개수 - 자바/Java (0) | 2023.01.06 |
[백준]2750 수 정렬하기 2 - 자바/Java (0) | 2023.01.05 |
[백준]1517 버블 소트 - 자바/Java (0) | 2023.01.05 |