[C++] 11657 - 타임머신 (골드4)

2022. 7. 14. 22:42·Coding Test/Solution

1. 문제 설명

 

11657번: 타임머신

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

www.acmicpc.net

 


2. 아이디어

다익스트라 알고리즘인 줄 알았는데 타임머신을 쓰면 음의 가중치가 더해진다.

최적의 해를 찾기 위해서는 비용이 적게 드는 간선을 골라야 하는데 음의 가중치가 있으면 '되돌아간다'의 개념이 아니라 '음의 비용'으로 이동하게 되기 때문에 최적의 해를 찾을 수 없게 된다.

이 경우엔 다른 알고리즘이 필요할 것 같아서 찾아보니 역시나 벨만 포드 알고리즘이란 걸 써야 한다.

 

다익스트라처럼 하나의 정점에서 다른 정점으로 가는 최단거리를 찾지만, 음의 가중치가 있어도 계산이 가능하다.

다만, 고려해야할 경우가 많아지고 로직 자체가 바뀌면서 시간 복잡도가 O(ElogV)에서 O(EV)로 느려진다.

 

벨만 포드 알고리즘의 시작은 출발 노드를 설정하고 최단 거리 테이블을 초기화하는 것은 다익스트라와 같다.

그리고 다음의 과정을 n-1번만큼 반복해야 한다.

  1.  모든 간선 E개를 하나씩 확인한다.
  2.  각 간선을 이용하여 다음 테이블로 가는 최단 거리 테이블을 갱신한다.

만약 현재 정점의 최단 거리 테이블 정보가 INF라면 2번 작업은 수행하지 않고 continue시킨다.

그리고 문제 조건에 '시간을 무한히 오래 돌릴 수 있다면...'은 음의 간선 순환의 존재 여부를 묻는 것이다.

 

음의 간선 순환

음의 간선 순환이란 위의 경우처럼 무한대의 최단 거리 테이블이 생성되는 경우를 말한다.

사실, 이걸 확인하는 방법은 굉장히 간단하다. 위에서 이미 갱신이 끝났어야 할 최단거리 테이블이

똑같은 반복문을 다시 돌렸을 때, 또 최단거리 테이블이 갱신이 된다면 음의 간선 순환이 존재하는 것이다.

 

여기서 예외처리가 발생하지 않는다면 갱신된 최단 거리 테이블을 조건에 맞게 출력시키면 된다.

 


3. 코드

#include <iostream>
#include <vector>
#include <algorithm>
#include <tuple>

#define MAX 501
#define INF 2147483647

using namespace std;

vector<tuple<int, int, int>> graph;
vector<long long> Dist(MAX, INF);

void bellman_ford(int n) {
    Dist[1] = 0;
    for (int i = 1; i <= n-1; i++) {
        for (auto j: graph) {
            int u, v, w;
            u = get<0>(j); v = get<1>(j); w = get<2>(j);

            if (Dist[u] == INF) continue;
            if (Dist[v] > Dist[u] + w) Dist[v] = Dist[u] + w;
        }
    }

    for (auto i: graph) {
        for (auto j: graph) {
            int u, v, w;
            u = get<0>(j); v = get<1>(j); w = get<2>(j);

            if (Dist[u] == INF) continue;
            if (Dist[v] > Dist[u] + w) {
                cout << -1 << "\n";
                return;
            }
        }
    }

    for (int i=2; i <= n; i++) {
        if (Dist[i] == INF) cout << -1 << "\n";
        else cout << Dist[i] << "\n";
    }
}

int main(void) {
    ios::sync_with_stdio(false);
    cin.tie(NULL);
    cout.tie(NULL);

    int n, m; cin >> n >> m;

    for (int i=0; i<m; i++) {
        int u,v,w; cin >> u >> v >> w;
        graph.push_back({u, v, w});
    }

    bellman_ford(n);

    return 0;
}
저작자표시 비영리 (새창열림)
'Coding Test/Solution' 카테고리의 다른 글
  • [C++] 2208 - 보석 줍기 (골드2)
  • [C++] 2056 - 작업 (골드5)
  • [C++] 2494 - 숫자 맞추기 (골드1)
  • [C++] 1916 - 최소비용 구하기 (골드5)
나죽못고나강뿐
나죽못고나강뿐
싱클레어, 대부분의 사람들이 가는 길은 쉽고, 우리가 가는 길은 어려워요. 우리 함께 이 길을 가봅시다.
  • 나죽못고나강뿐
    코드를 찢다
    나죽못고나강뿐
  • 전체
    오늘
    어제
    • 분류 전체보기 (458)
      • Computer Science (60)
        • Git & Github (4)
        • Network (17)
        • Computer Structure & OS (13)
        • Software Engineering (5)
        • Database (9)
        • Security (5)
        • Concept (7)
      • Frontend (21)
        • React (13)
        • Android (4)
        • iOS (4)
      • Backend (77)
        • Spring Boot & JPA (50)
        • Django REST Framework (14)
        • MySQL (8)
        • Nginx (1)
        • FastAPI (4)
      • DevOps (24)
        • Docker & Kubernetes (11)
        • Naver Cloud Platform (1)
        • AWS (2)
        • Linux (6)
        • Jenkins (0)
        • GoCD (3)
      • Coding Test (112)
        • Solution (104)
        • Algorithm (7)
        • Data structure (0)
      • Reference (134)
        • Effective-Java (90)
        • Pragmatic Programmer (0)
        • CleanCode (11)
        • Clean Architecture (2)
        • Test-Driven Development (4)
        • Relational Data Modeling No.. (0)
        • Microservice Architecture (2)
        • 알고리즘 문제 해결 전략 (9)
        • Modern Java in Action (0)
        • Spring in Action (0)
        • DDD start (0)
        • Design Pattern (6)
        • 대규모 시스템 설계 (6)
        • JVM 밑바닥까지 파헤치기 (4)
      • Service Planning (2)
      • Side Project (5)
      • AI (0)
      • MATLAB & Math Concept & Pro.. (1)
      • Review (18)
      • Interview (2)
      • IT News (2)
  • 블로그 메뉴

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

    • 깃
  • 공지사항

    • 한동안 포스팅은 어려울 것 같습니다. 🥲
    • N Tech Service 풀스택 신입 개발자가 되었습니다⋯
    • 취업 전 계획 재조정
    • 취업 전까지 공부 계획
    • 앞으로의 일정에 대하여..
  • 인기 글

  • 태그

  • 최근 댓글

  • 최근 글

  • hELLO· Designed By정상우.v4.10.2
나죽못고나강뿐
[C++] 11657 - 타임머신 (골드4)

개인정보

  • 티스토리 홈
  • 포럼
  • 로그인
상단으로

티스토리툴바

단축키

내 블로그

내 블로그 - 관리자 홈 전환
Q
Q
새 글 쓰기
W
W

블로그 게시글

글 수정 (권한 있는 경우)
E
E
댓글 영역으로 이동
C
C

모든 영역

이 페이지의 URL 복사
S
S
맨 위로 이동
T
T
티스토리 홈 이동
H
H
단축키 안내
Shift + /
⇧ + /

* 단축키는 한글/영문 대소문자로 이용 가능하며, 티스토리 기본 도메인에서만 동작합니다.