Code.Dev_MH
DevMHK
Code.Dev_MH
전체 방문자
오늘
어제
  • 개발자의 일상 (40)
    • Language (5)
      • Java (4)
      • Kotlin (1)
      • Python (0)
    • Back-End (1)
      • Spring (1)
      • Django (0)
      • Error (0)
    • Infra (0)
      • Docker (0)
      • CI, CD (0)
      • AWS (0)
    • CS (12)
      • 컴퓨터 구조(Computer Architectur.. (12)
      • 운영 체제(OS) (0)
      • 시스템소프트웨어(SystemSoftware) (0)
      • 네트워크(Network) (0)
      • 소프트웨어공학(Software Engineerin.. (0)
      • 데이터베이스(DataBase) (0)
      • 자료구조(Data Structure) (0)
      • 알고리즘(Algorithm) (0)
    • Git (0)
    • Algorithm (21)
      • 프로그래머스 (5)
      • 백준 (16)
      • 코딩테스트 후기 (0)
    • 회고 (1)

블로그 메뉴

  • 홈
  • 태그
  • 방명록

공지사항

인기 글

태그

  • Priority Queue
  • BFS
  • 코틀린장점
  • INT
  • 다이나믹프로그래밍
  • 컴퓨터구조
  • 프로그래머스
  • computer architecture
  • 그리디
  • java
  • dp
  • cs
  • 브루트포스
  • 코틀린사용이유
  • 백준
  • 우선순위 큐
  • 자바와비교
  • 제로베이스백엔드스쿨
  • Greedy
  • 너비우선탐색

최근 댓글

최근 글

티스토리

hELLO · Designed By 정상우.
Code.Dev_MH

DevMHK

[백준_11657] 타임머신
Algorithm/백준

[백준_11657] 타임머신

2022. 12. 27. 12:00

문제

백준 11657번
https://www.acmicpc.net/problem/11657

N개의 도시가 있다. 그리고 한 도시에서 출발하여 다른 도시에 도착하는 버스가 M개 있다. 각 버스는 A, B, C로 나타낼 수 있는데, A는 시작도시, B는 도착도시, C는 버스를 타고 이동하는데 걸리는 시간이다. 시간 C가 양수가 아닌 경우가 있다. C = 0인 경우는 순간 이동을 하는 경우, C < 0인 경우는 타임머신으로 시간을 되돌아가는 경우이다.

첫째 줄에 도시의 개수 N (1 ≤ N ≤ 500), 버스 노선의 개수 M (1 ≤ M ≤ 6,000)이 주어진다. 둘째 줄부터 M개의 줄에는 버스 노선의 정보 A, B, C (1 ≤ A, B ≤ N, -10,000 ≤ C ≤ 10,000)가 주어진다.

만약 1번 도시에서 출발해 어떤 도시로 가는 과정에서 시간을 무한히 오래 전으로 되돌릴 수 있다면 첫째 줄에 -1을 출력한다. 그렇지 않다면 N-1개 줄에 걸쳐 각 줄에 1번 도시에서 출발해 2번 도시, 3번 도시, ..., N번 도시로 가는 가장 빠른 시간을 순서대로 출력한다. 만약 해당 도시로 가는 경로가 없다면 대신 -1을 출력한다.

  • 예시
  • 1 -> 2로 갈때 시간이 4
  • 1 -> 2 -> 3으로 갈 때 3 그리고 1 -> 3 으로 갈 때 3
  • 1 에서 다시 1로 돌아오면 1로 이전인 0보다 큰 값이기에 이후 이동해도 더 빨리 가는 시간은 나오지 않는다.

Code

간선에 음수가 있었기 때문에 다익스트라가 아닌 벨만-포드로 풀어야 했다. 하지만, 모든 간선을 방문해야하기 때문에 다익스트라보다는 느리다!! 간선에 음수가 없다면 무조건 다.익.스.트.라!!

Java

import java.util.*;

public class Main {

    static class Edge {
        int from;
        int to;
        int weight;

        public Edge(int from, int to, int weight) {
            this.from = from;
            this.to = to;
            this.weight = weight;
        }
    }

    final static int INF = 1000000000;
    static Edge[] edge;
    static long[] dist;

    public static void solution(int N, int M, int[][] data, int start) {
        edge = new Edge[M];
        for (int i = 0; i < M; i++) {
            edge[i] = new Edge(data[i][0], data[i][1], data[i][2]);
        }

        dist = new long[N + 1];  // 최단 경로 배열 초기화
        for (int i = 1; i < N + 1; i++) {
            dist[i] = INF;
        }
        dist[start] = 0;

        if (bellmanFord(N, M)) {  // 음수 사이클이 나올 경우
            System.out.println(-1);
        } else {
            for (int i = 2; i < N + 1; i++) {
                if (dist[i] == INF) {  
                // 음수 사이클은 아니지만, 갈 수 있는 방법이 없을 때
                    System.out.println(-1);
                } else {
                    System.out.println(dist[i]);
                }
            }
        }
    }

        public static boolean bellmanFord(int N, int M) {
            boolean isMinusCycle = false;
            for (int i = 0; i < N + 1; i++) {
                for (int j = 0; j < M; j++) {
                    Edge cur = edge[j];

                    if (dist[cur.from] == INF) {
                        continue;
                    }

                    if (dist[cur.to] > dist[cur.from] + cur.weight) {
                    // 현재 위치에서 다른 노드로 이동하는 거리가 더 짧을 경우
                        dist[cur.to] = dist[cur.from] + cur.weight;

                        // 음수 사이클 체크
                        if (i == N) {
                            isMinusCycle = true;
                        }
                    }
                }
            }
            return isMinusCycle;
        }

    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        int N = sc.nextInt();  // 도시의 개수
        int M = sc.nextInt();  // 버스 노선의 개수

        int[][] data = new int[M][3];  // 
        for (int i = 0; i < M; i++) {
            for (int j = 0; j < 3; j++) {
                data[i][j] = sc.nextInt();
            }
        }
        solution(N, M, data, 1);
    }     
}

  • 첫 번째 예제로만 해설할 예정이고, 나머지 예제도 같은 방법으로 해결 가능!
  • 먼저, data값들을 edge로 간선을 구성한다.
  • 그리고 거리 배열인 dist를 만들어주고 음수사이클 체크할 boolean도 하나 만들어 준다.
  • 그리고 start값은 0으로 초기화 시켜준다.

  • 0번째 edge로 거리 확인
  • 원래 dist가 INF 였기 때문에 더 작은 값인 4로 바꾸어 준다.

  • 1번째 edge로 거리 확인
  • 원래 dist가 INF 였기 때문에 더 작은 값인 3로 바꾸어 준다.

  • 2번째 edge로 거리 확인
  • 원래 dist가 3으로 우측 식 계산 값 또한, 3으로 변경되지 않는다.

  • 3번째 edge로 거리 확인
  • 원래 dist가 0으로 우측 식 계산 값 또한, 1로 좌측보다 크기 때문에 변경되지 않는다.

  • 최종적으로 나온 1번 도시에 2, 3, ... N번 도시로 가는 가장 빠른 시간이다.
반응형

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

[백준_15904] UCPC는 무엇의 약자일까?  (1) 2023.01.06
[백준_1260] DFS와 BFS  (0) 2023.01.05
[백준_1254] 팰린드롬 만들기  (0) 2023.01.03
[백준_2075] N번째 큰 수  (1) 2023.01.01
[백준_18352] 특정 거리의 도시 찾기  (1) 2022.12.26
    'Algorithm/백준' 카테고리의 다른 글
    • [백준_1260] DFS와 BFS
    • [백준_1254] 팰린드롬 만들기
    • [백준_2075] N번째 큰 수
    • [백준_18352] 특정 거리의 도시 찾기
    Code.Dev_MH
    Code.Dev_MH
    Back-End 개발자가 되기 위한 개발 노트(Java)

    티스토리툴바