https://github.com/Dev-Guccin
Guccin
https://github.com/Dev-Guccin
전체 방문자
오늘
어제
  • 분류 전체보기 (172)
    • 알고리즘 (140)
    • 삽질방지 (13)
    • SystemHacking (1)
    • 일상 (4)
    • 개발 (8)
    • 스프링 부트 REST API 개발일지 (5)
    • JPA (1)

블로그 메뉴

  • 홈
  • 태그
  • 방명록

공지사항

인기 글

태그

  • 백준
  • 유클리드호제법
  • 12015
  • counter
  • 파이썬
  • 백트래킹
  • DP
  • 재귀함수
  • 프로그래머스
  • 최단경로
  • MST
  • 다익스트라
  • 다이나믹프로그래밍
  • 그리디
  • 재귀
  • 그래프
  • 최소힙
  • 최대공약수
  • heapq
  • 큐
  • 유니온 파인드
  • 이분탐색
  • 스택
  • 다이나믹 프로그래밍
  • LIS
  • Python
  • 이분 탐색
  • DFS
  • BFS
  • python3

최근 댓글

최근 글

티스토리

hELLO · Designed By 정상우.
https://github.com/Dev-Guccin

Guccin

[c++] 백준 11657 풀이 ( 타임머신, 최단경로, 벨만-포드, 음수 가중치 )
알고리즘

[c++] 백준 11657 풀이 ( 타임머신, 최단경로, 벨만-포드, 음수 가중치 )

2021. 8. 6. 17:35

우선 이 문제를 풀기위해서는 벨만-포드 알고리즘을 이해해야한다.

벨만-포드

  1. 단일시작점 알고리즘 (출발 노드가 고정)
  2. 최단 경로 알고리즘
  3. 음수 간선 가능
  4. 음수 사이클 확인 가능

쓱 보면 다익스트라와 비슷해보인다.(https://guccin.tistory.com/112?category=977502)
그러나 다익스트라와 달리 벨만-포드 알고리즘은 음수 간선에 대해서 최단거리를 알아낼수 있다.
또한 다익스트라는 우선순위 큐를 활용하여 최단 경로를 구하는데에 반해 벨만-포드는 매번 모든 간선을 전부 확인하며 최단거리를 알아내기 때문에 다익스트라보다 시간복잡도가 크다. 다익스트라 O(|E||log|V|), 벨만-포드 O(|E||V|)

 

[c++] 백준 1753 풀이 ( 최단 경로, 다익스트라, 그래프, 우선순위 )

다익스트라 다익스트라는 다이나믹 프로그래밍을 활용한 최단경로 탐색 알고리즘이다. 단일 시작점 알고리즘에 속하여 시작점을 기준으로 각 노드까지의 최단 거리를 알 수 있다. 이때 시간 복

guccin.tistory.com

 

벨만-포드 진행과정

  1. 최단거리 테이블 초기화
  2. 출발노드 설정
  3. V번 루프를 돈다.
  4. 중간노드 루프를 돈다.
  5. 중간노드의 간선들을 확인하여 upper 배열을 완화시킨다.
  6. V번째 루프에서 음수사이클이 존재하는지 판단한다.(완화가 일어났는지 확인)

그럼 대강 알았으니 더 공부하기 위해서는 동빈나님의 영상을 참고하면 좋을것 같다.(https://www.youtube.com/watch?v=Ppimbaxm8d8)

이제 문제에 접근해보자

문제에서 주어지는 것은 그래프의 노드 개수와 간선 정보이다. 여기서 주요 포인트는 아래와 같다.


* 양수가 아닌 음수 가중치가 존재한다.
* 출발지가 1로 고정되기 때문에 단일 시작점 알고리즘이다.
* 시간을 무한히 오래전으로 되돌릴수 있다는 의미는 음수 사이클이 존재할 수 있다는 소리다.

그렇다면 결론적으로 다익스트라를 사용할 수 없다. 따라서 음수 가중치의 최단 경로를 구할 수 있고 음수 사이클까지 확인 가능한 벨만-포드 알고리즘을 사용해야 한다.

그럼 이를 토대로 코드를 짜면된다.
이때 주의해야 할 것은 가중치의 최댓값이 int가 아닌 long long이어야 한다는점.
또한, 언더플로우와 오버플로우를 막기 위해 중간노드의 최단거리가 이미 INF라면 연산을 생략해준다는 점이다.

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

#define MAX_N 501
#define INF 200000000000000000
using namespace std;
int N, M;
vector<pair<int, int>> adj[MAX_N];

void bellman() {
	// upper를 INF로 초기화, src 초기화
	vector<long long> upper(N + 1, INF);
	upper[1] = 0;//1에서 1로 가는 경우 비용 0

	// 완화 체크
	int updated = 0;
	// v만큼 반복
	for (int iter = 0; iter < N; iter++)
	{
		updated = 0;
		for (int here = 1; here <= N; here++)//S -> 들러갈 노드(here)
			for (int j = 0; j < adj[here].size(); j++)// S -> 들러갈 노드 -> 도착 노드(adj[here][j])
			{
				int end = adj[here][j].first;
				int cost = adj[here][j].second;
				// 중간노드까지의 값이 INF라면 의미가 없는것은 물론,
				// 언더플로우나 오버플로우가 일어날 가능성이 존재한다.
				if (upper[here] == INF)
					continue;

				if (upper[end] > upper[here] + cost) {
					upper[end] = upper[here] + cost;
					updated = 1;
				}
			}
		if (updated == 0)// 이건 왜 들어가야하는지 정확히 모르겠다.
			break;
	}
	// 마지막 V번째 루프(음수사이클 판별)에서 완화가 일어났으면 음수 사이클 존재
	if (updated == 1) {
		upper.clear();
		cout << -1 <<'\n';
		return;
	}
	for (int i = 2; i <= N; i++)
	{
		if (upper[i] != INF)
			cout << upper[i] << '\n';
		else
			cout << -1 << '\n';
	}
}
int main() {
	// 단일 시작점 알고리즘, 음수가중치 존재
	// 음수 사이클 존재 가능, 경로 없는 경우 가능
	cin >> N >> M;
	int A, B, C;
	for (int i = 0; i < M; i++)
	{
		cin >> A >> B >> C;
		adj[A].push_back({ B,C });
	}
	bellman();
}

 

이를 코드로 짜는 것은 얼마 걸리지 않았지만, 문제는 제출이 안되고 계속 틀렸다. 알고보니 언더플로우와 오버플로우를 예상하지 못했다. 이는 실제 프로그래밍에서 더 심각한 문제를 발생할 수 있기때문에 더 주의해야한다.

결론 : 벨만-포드는 음수 가중치, 음수 사이클, O(VE) 등등의 속성을 가진다는 것을 잘 머리에 박아놓자.

저작자표시 (새창열림)

'알고리즘' 카테고리의 다른 글

[c++] 백준 1629 풀이 ( 곱셈, 분할 정복을 이용한 거듭제곱, long long )  (0) 2021.08.09
[python3] 백준 2252 풀이 ( 줄세우기, 위상정렬, DAG, 그래프 )  (0) 2021.08.07
[python3] 백준 10844 풀이 ( 쉬운 계단 수, 다이나믹 프로그래밍, 이차 배열)  (0) 2021.08.05
[c++] 백준 1753 풀이 ( 최단 경로, 다익스트라, 그래프, 우선순위 )  (0) 2021.08.04
[c++] 백준 1197 풀이 (MST, 최소 신장 트리, 그래프, 유니온 파인드)  (0) 2021.08.02
    '알고리즘' 카테고리의 다른 글
    • [c++] 백준 1629 풀이 ( 곱셈, 분할 정복을 이용한 거듭제곱, long long )
    • [python3] 백준 2252 풀이 ( 줄세우기, 위상정렬, DAG, 그래프 )
    • [python3] 백준 10844 풀이 ( 쉬운 계단 수, 다이나믹 프로그래밍, 이차 배열)
    • [c++] 백준 1753 풀이 ( 최단 경로, 다익스트라, 그래프, 우선순위 )
    https://github.com/Dev-Guccin
    https://github.com/Dev-Guccin
    https://github.com/Dev-Guccin

    티스토리툴바