728x90
1219번: 오민식의 고민
첫째 줄에 도착 도시에 도착할 때, 가지고 있는 돈의 액수의 최댓값을 출력한다. 만약 오민식이 도착 도시에 도착하는 것이 불가능할 때는 "gg"를 출력한다. 그리고, 오민식이 도착 도시에 도착
www.acmicpc.net
벨만-포드 알고리즘
- 특정 출발 노드에서 다른 모든 노드까지의 최단경로 검색
- 음수 가중치 존재
- 음수 싸이클 존재 여부 판단
- 2023.03.20 - [Algorithm/Graph] - [11657번] 타임머신 (그래프, 최단거리, 벨만 포드 알고리즘)
- 수행과정
- 모든 에지와 관련된 정보를 가져와 다음 조건에 따라 거리 리스트의 값 업데이트
- 출발 노드가 방문한 적이 없는 노드(출발 노드 거리 == INF) 일 때 업데이트 X
- 출발 노드의 거리 리스트 값 + 에지 가중치 < 종료노드의 거리 리스트 값일 때, 종료 노드 거리 리스트값 업데이트
- 노드 개수 -1번 만큼 반복
- 노드의 개수가 N이고 음수 사이클이 없을 때 특 정 두 노드의 최단 거리를 구성할 수 있는 에지의 최대 갯수 N-1
- 음수 사이클 유무를 알기 위해 모든 에지에 관해 1 수행, 한 번 이라도 값이 업데이트 되면 음수 사이클 존재로 판단
- 모든 에지와 관련된 정보를 가져와 다음 조건에 따라 거리 리스트의 값 업데이트
변형된 벨만-포드 알고리즘
- 돈을 무한히 많이 버는 케이스가 있다고 하는 것을 바탕으로 음수 사이클이 아닌 양수 사이클을 찾도록 변경
- 양수 사이클이 있어도 출발 노드에서 이 양수 사이클을 이용해 도착 도시에 가지 못할 때 예외처리
- 수행과정
- 모든 에지와 관련된 정보를 가져와 다음 조건에 따라 거리 리스트의 값 업데이트
- 시작 도시가 방문한 적이 없는 도시일 때 (시작 도시==MIN) 업데이트 X
- 시작 도시가 양수 사이클과 연결된 도시일때 (도착도시 == MAX) 도착 도시도 양수 사이클과 연결된 도시로 업데이트
- 도착 도시값 < 시작 도시값 + 도착 도시 수입 - 에지 가중치일 때, 더 많이 벌 수 있는 새로운 경로로 도착 업데이트
- 노드보다 충분히 많은 값(N+100)으로 1 반복
- 에지의 업데이트를 충분히 큰 수(도시 개수 N의 최대치=100)만큼 추가로 돌리면서 업데이트 수행
- 에지를 충분히 탐색하면서 양수 사이클에서 도달할 수 있는 모든 노드를 양수 사이클에 연결된 노드로 업데이트하기 위해
- 모든 에지와 관련된 정보를 가져와 다음 조건에 따라 거리 리스트의 값 업데이트
풀이
"""
도시수 n(1~100), 시작, 종료, 교통수단 m(1~100)
교통 수단 정보 : 시작 끝 가격
각 도시에서 벌 수 있는 돈의 최댓값(0~1,000,000)
같은 도시 여러번 방문 가능
버는 돈보다 쓰는 돈이 많다면 도착 도시에 도착할때 지니고 있는 돈의 액수가 음수
* 도착도시에 도착할 때 지니고 있는 돈의 최대 액수
도착 불가 'gg'
무한 'Gee'
"""
import sys
input=sys.stdin.readline
# 도시수 n(1~100), 시작, 종료, 교통수단 m(1~100)
n,s,e,m=map(int, input().split())
graph = [] # 교통 수단 정보, 에지 리스트
d = [-sys.maxsize]*n # 최단 경로 리스트
# 교통 수단 정보, 에지 리스트
for _ in range(m):
u, v, w = map(int, input().split())
graph.append((u, v, w))
# 각 도시에서 벌 수 있는 돈의 최댓값
mList=list(map(int,input().split()))
d[s] = mList[s]
# 변형 벨만-포드
for i in range(n+101):
for start, end, price in graph:
if d[start]==-sys.maxsize: # 출발노드 미방문 노드
continue
elif d[start]==sys.maxsize: # 출발노드가 양수 사이클에 연결된 노드
d[end]=sys.maxsize
elif d[end] < d[start]+mList[end]-price: # 종료노드값 < 출발노드값+도착도시수입+에지가중치
d[end]=d[start]+mList[end]-price
# 에지 사용 횟수가 n-1을 넘어선 이후 갱신되면 양수 사이클에 연결되어 있다는 의미
# 종료노드를 양수 사이클 연결 노드로 업데이트
if i >= n-1:
d[end]=sys.maxsize
if d[e] == -sys.maxsize: # 도착 불가능
print("gg")
elif d[e]==sys.maxsize: # 양수싸이클, 무한대
print("Gee")
else:
print(d[e])
728x90