99클럽 코테 스터디 8일차 TIL

2024. 11. 4. 18:34·코딩테스트/99클럽 4기

백준 - 2644번

'앞에 나오는 번호 x는 뒤에 나오는 정수 y의 부모 번호를 나타낸다.'

이 부분을 보고 부모 번호에서부터 시작되는 단방향 그래프로 생각했다.

그 생각에서 1시간을 넘게 벗어나지 못했다.

 

그리고 탐색은 무조건 1에서부터 시작해야한다는 고정관념이 있었다.

실제 촌수 계산할 때, 자신(나)부터 거슬러올라가면서 계산한다.

그래프 탐색 알고리즘 사용만을 생각하고, 문제와 상관없이 형식적으로 알고리즘을 사용했던 것 같다.

 

DFS 풀이

예제에서 촌수 계산을 해야하는 사람인 7번과 3번을 기준으로 계산해야 한다.

  • 단방향이 아닌 양방향 그래프를 그린다.
  • 7번부터 시작하여 3번까지 탐색한다.
  • depth가 깊어질 때마다 count를 줘야 한다.
import java.util.ArrayList;
import java.util.Scanner;

public class Main {

    static ArrayList<Integer>[] relations; // 관계도
    static boolean[] visited; // 방문 여부
    static int result = -1;
    
    static void dfs(int current, int target, int depth) {
        visited[current] = true;

        if (current == target) {
            result = depth;
            return;
        }

        for (int next : relations[current]) {
            if (!visited[next]) {
                dfs(next, target, depth + 1);

                if (result != -1) return;
            }
        }
    }

    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);

        int n = sc.nextInt();
        int start = sc.nextInt();
        int end = sc.nextInt();
        int m = sc.nextInt();

        relations = new ArrayList[n + 1];
        visited = new boolean[n + 1];
        for (int i = 1; i <= n; i++) {
            relations[i] = new ArrayList<>();
        }
        
        // 양방향 그래프
        for (int i = 0; i < m; i++) {
            int x = sc.nextInt();
            int y = sc.nextInt();
            relations[x].add(y);
            relations[y].add(x);
        }

        dfs(start, end, 0);

        System.out.println(result);
        sc.close();
    }
}

DFS를 사용했지만 BFS도 사용할 수 있다.

그림에서는 트리 모양으로 그렸고, 간선도 직선 방향이다보니 DFS 밖에 생각나지 않았다.

 

BFS 풀이

7번을 기준으로, 다른 번호들은 7번과 몇 촌인지 기록하면서 탐색한다.

촌수 기록을 위한 distance 라는 배열 변수를 새로 선언했다.

static int bfs(int start, int end) {
    Queue<Integer> queue = new LinkedList<>();
    queue.add(start);
    visited[start] = true;
    distance[start] = 0;

    while (!queue.isEmpty()) {
        int current = queue.remove();

        if (current == end) {
            return distance[current];
        }

        for (int next : relations[current]) {
            if (!visited[next]) {
                visited[next] = true;
                distance[next] = distance[current] + 1; // 각 번호마다 촌수 기록
                queue.add(next);
            }
        }
    }

    return -1;
}

아래의 표는 bfs 함수를 돌면서 각 번호가 7번과 몇 촌에 있는지 계산하는 것을 나타낸다.

내가 이해 안되서 작성했다.

촌수 계산 촌수 현재 queue 상태
distance[2] = distance[7] + 1 1촌 2
distance[1] = distance[2] + 1 2촌 1
distance[8] = distance[2] + 1 2촌 1 8
distance[9] = distance[2] + 1 2촌 1 8 9
distance[3] = distance[1] + 1 3촌 8 9 3

순차적으로 queue의 값을 꺼내고 종료값인 3이 오면 bfs 함수를 종료하고 결과를 출력한다.


지금까지 작성한 코드를 봤을 때, BFS 보다는 DFS 의 코드의 양도 적고 더 깔끔한 것 같다.

하지만 코드를 분석해보면 작은 범위이지만 재귀 함수가 호출될 때마다 내 머리의 복잡도가 높아졌다.

개인적으로 머리 복잡도가 높으면 값의 예측이 안될 때가 많았다.

BFS의 경우, 코드는 길지만 DFS와 반대로 깊어지는 사고에서 빠르게 나올 수 있었다.

 

백준 2644번 - 촌수계산

https://www.acmicpc.net/problem/2644

저작자표시 (새창열림)

'코딩테스트 > 99클럽 4기' 카테고리의 다른 글

99클럽 코테 스터디 10일차 TIL  (2) 2024.11.06
99클럽 코테 스터디 9일차 TIL  (2) 2024.11.05
99클럽 코테 스터디 7일차 TIL  (0) 2024.11.03
99클럽 코테 스터디 6일차 TIL  (0) 2024.11.02
99클럽 코테 스터디 5일차 TIL  (0) 2024.11.01
'코딩테스트/99클럽 4기' 카테고리의 다른 글
  • 99클럽 코테 스터디 10일차 TIL
  • 99클럽 코테 스터디 9일차 TIL
  • 99클럽 코테 스터디 7일차 TIL
  • 99클럽 코테 스터디 6일차 TIL
tjdgus
tjdgus
  • tjdgus
    Do It...
    tjdgus
  • 전체
    오늘
    어제
    • 분류 전체보기
      • Language
        • Java
      • CS
        • Data Structure
        • OS
        • Algorithm
        • Network
      • 오류 모음집
      • ETC
      • 함수형 프로그래밍
      • JPA
      • Toy
      • 데이터베이스
      • Spring
      • 코딩테스트
        • 99클럽 4기
  • 블로그 메뉴

    • 홈
    • 태그
    • 방명록
  • 링크

  • 공지사항

  • 인기 글

  • 태그

    99클럽
    TiL
    개발자취업
    오블완
    티스토리챌린지
    코딩테스트준비
    항해99
  • 최근 댓글

  • 최근 글

  • hELLO· Designed By정상우.v4.10.0
tjdgus
99클럽 코테 스터디 8일차 TIL
상단으로

티스토리툴바