(백준) 최소 환승 경로 - 2021 [java]

2021. 8. 18. 15:21·알고리즘/백준

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

 

🐢 설명

올리브영 코테에 나온 문제랑 비슷한 문제라서 풀게되었다.

 

출발 역과 도착 역이 주어지면 몇번 환승해서 도달할 수 있는지 알아내는 문제이다. 처음에는 문제가 잘 이해가 안되었는데 역 번호들이 나열된 하나의 행이 노선이라고 생각하면 된다.

 

구현

노선별 역을 담을 리스트와 역별로 자신을 지나가는 노선을 담을 리스트 두개를 만들어주었다.

방문체크 또한 해당 노선을 방문했는지 여부와 해당 역을 방문했는지 여부를 체크하기 위해 방문체크용 배열 두개를 만들어 주었다.

 

최소의 환승 횟수를 출력해야하므로 환승 횟수를 기준으로 갖는 우선순위큐를 사용했다.

 

주어진 출발역이 하나의 노선이 아니라 여러 노선에 담겨있을 수도 있으므로 라인 별로 해당 역을 우선순위큐에 넣어주고 각 라인들은 방문체크를 해주었다. 출발역 또한 방문체크를 해주었다.

 

이후 우선순위 큐에서 하나를 뽑으면 (현재 노선, 현재 역, 환승 횟수)를 갖고있는데 해당 역을 방문한적이 없다면 두가지 방법이 존재한다

  1. 환승하지 않고 계속 가는방법
  2. 환승하는 방법

따라서 이를 둘다 우선순위 큐에 담아주었다. 큐를 다 돌때까지 도착역을 만나지 못하면 -1을 출력하고, 만난다면 그때가 최소 환승 횟수를 가진 객체이므로 바로 출력하도록 했다.

 

🐢코드
public class 최소환승경로_2021 {
    static int N, M;
    static boolean[] visitedLine;
    static boolean[] visitedStation;
    static ArrayList<Integer>[] stations;
    static ArrayList<Integer>[] lines;
    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());

        visitedLine = new boolean[M + 1];
        visitedStation = new boolean[N + 1];
        stations = new ArrayList[N + 1];
        lines = new ArrayList[N + 1];
        for (int i = 1; i < N + 1; i++) {
            stations[i] = new ArrayList<>();
            lines[i] = new ArrayList<>();
        }

        for (int i = 1; i <= M; i++) {
            String[] s = br.readLine().split(" ");
            for (String station : s) {
                int statN = Integer.parseInt(station);
                if (statN == -1) break;
                stations[statN].add(i);
                lines[i].add(statN);
            }
        }

        st = new StringTokenizer(br.readLine());
        int start = Integer.parseInt(st.nextToken());
        int end = Integer.parseInt(st.nextToken());

        int answer = go(start, end);
        System.out.println(answer);
    }

    private static int go(int start, int end) {
        PriorityQueue<Node> pq = new PriorityQueue<>(Comparator.comparingInt(n -> n.transCount));
        visitedStation[start] = true;
        for (int line : stations[start]) {
            pq.add(new Node(line, start, 0));
            visitedLine[line] = true;
        }

        while (!pq.isEmpty()) {
            Node now = pq.poll();

            if (now.curStation == end) {
                return now.transCount;
            }

            for (int nextStation : lines[now.curLine]) {

                if (!visitedStation[nextStation]) {
                    visitedStation[nextStation] = true;
                    pq.add(new Node(now.curLine, nextStation, now.transCount));

                    for (int nextLine : stations[nextStation]) {
                        if (!visitedLine[nextLine]) {
                            visitedLine[nextLine] = true;
                            pq.add(new Node(nextLine, nextStation, now.transCount + 1));
                        }
                    }
                }
            }
        }
        return -1;
    }

    private static class Node {
        int curLine;
        int curStation;
        int transCount;

        public Node(int curLine, int curStation, int transCount) {
            this.curLine = curLine;
            this.curStation = curStation;
            this.transCount = transCount;
        }
    }
}
🐢 마무리

방문체크를 역과 노선을 구분해서 해주면 풀수있는 문제였다.

반응형
저작자표시 (새창열림)

'알고리즘 > 백준' 카테고리의 다른 글

(백준) 연료채우기_1826 [java]  (1) 2021.08.23
(백준) 컵라면 - 1781 [java]  (0) 2021.08.21
(백준) 달이 차오른다, 가자 - 1194 [java]  (0) 2021.08.17
(백준) 미친 아두이노 - 8972 [java]  (1) 2021.08.10
(백준) 단어암기 - 18119 [java]  (0) 2021.08.09
'알고리즘/백준' 카테고리의 다른 글
  • (백준) 연료채우기_1826 [java]
  • (백준) 컵라면 - 1781 [java]
  • (백준) 달이 차오른다, 가자 - 1194 [java]
  • (백준) 미친 아두이노 - 8972 [java]
구름뭉치
구름뭉치
구름의 개발일기장
    반응형
  • 구름뭉치
    구름 개발일기장
    구름뭉치
  • 전체
    오늘
    어제
    • ALL (288) N
      • 프로젝트 (23)
        • 토스페이먼츠 PG 연동 시리즈 (12)
        • JWT 방식 인증&인가 시리즈 (6)
        • 스우미 웹 애플리케이션 프로젝트 (1)
        • 스프링부트 기본 보일러 플레이트 구축 시리즈 (2)
        • 마이크로서비스 아키텍쳐 시리즈 (1)
      • 스프링 (43)
        • 스프링부트 API 설계 정리 (8)
        • 스프링부트 RestAPI 프로젝트 (18)
        • 스프링부트 WebSocket 적용기 (3)
        • 스프링 JPA 정리 시리즈 (5)
        • 스프링 MVC (5)
        • 스프링 배치 (2)
        • 토비의 스프링 정리 (2)
      • 기술 학습 (4) N
        • 아파치 카프카 (9)
        • 클린 코드 (4)
        • 디자인 패턴의 아름다움 (2)
        • 모던 자바 인 액션 (7)
        • JVM 스레드 딥다이브 (7)
      • Web (25)
        • 정리글 (20)
        • GraphQL 정리글 (2)
        • Jenkins 정리글 (3)
      • 취업 (6)
      • CS (77)
        • 네트워크 전공 수업 정리 (11)
        • OSI 7계층 정리 (12)
        • 운영체제 정리 (19)
        • 데이터베이스 정리 (5)
        • MySql 정리 (17)
        • GoF의 Design Pattern 정리 (12)
      • 알고리즘 (70)
        • 백준 (56)
        • 프로그래머스 (12)
        • 알고리즘 정리본 (1)
      • 기초 지식 정리 (2)
      • 일상 (8)
  • 블로그 메뉴

    • 홈
  • 링크

  • 공지사항

  • 인기 글

  • 태그

    마우스
    류블라냐
    mx master s3 for mac
    크로아티아
    레이저
    키보드 손목 받침대
    마우스 패드
    부다페스트
    동유럽
  • 최근 댓글

  • 최근 글

  • hELLO· Designed By정상우.v4.10.6
구름뭉치
(백준) 최소 환승 경로 - 2021 [java]
상단으로

티스토리툴바