[Gold IV] 최단경로 - 1753
성능 요약
메모리: 73872 KB, 시간: 1020 ms
분류
데이크스트라, 그래프 이론, 최단 경로
제출 일자
2023년 11월 1일 12:09:58
문제 설명
방향그래프가 주어지면 주어진 시작점에서 다른 모든 정점으로의 최단 경로를 구하는 프로그램을 작성하시오. 단, 모든 간선의 가중치는 10 이하의 자연수이다.
입력
첫째 줄에 정점의 개수 V와 간선의 개수 E가 주어진다. (1 ≤ V ≤ 20,000, 1 ≤ E ≤ 300,000) 모든 정점에는 1부터 V까지 번호가 매겨져 있다고 가정한다. 둘째 줄에는 시작 정점의 번호 K(1 ≤ K ≤ V)가 주어진다. 셋째 줄부터 E개의 줄에 걸쳐 각 간선을 나타내는 세 개의 정수 (u, v, w)가 순서대로 주어진다. 이는 u에서 v로 가는 가중치 w인 간선이 존재한다는 뜻이다. u와 v는 서로 다르며 w는 10 이하의 자연수이다. 서로 다른 두 정점 사이에 여러 개의 간선이 존재할 수도 있음에 유의한다.
출력
첫째 줄부터 V개의 줄에 걸쳐, i번째 줄에 i번 정점으로의 최단 경로의 경로값을 출력한다. 시작점 자신은 0으로 출력하고, 경로가 존재하지 않는 경우에는 INF를 출력하면 된다.
틀린 문제 풀이
문제를 읽고 Dijkstra 알고리즘으로 해보자는 생각이 들었음.
하지만 메모리 초과가 발생했음.
V,E = list(map(int,input().split()))
start = int(input())
graph = [[200001]*(V+1) for _ in range(V+1)]
for i in range(1,V+1):
graph[i][i] = 0
for i in range(E):
temp = list(map(int,input().split()))
graph[temp[0]][temp[1]] = temp[2]
answer = graph[start][:]
for i in range(1,V+1):
for j in range(1,V+1):
answer[j] = min(answer[j],answer[i]+graph[i][j])
for i in range(1,V+1):
if answer[i] == 200001:
print('INF')
else:
print(answer[i])
그래서 아래와 같은 코드로 딕셔너리를 사용하여 메모리 낭비를 줄이고자 시도함
하지만 애초에 Dijkstra에 대해 잘못 이해하고 있었다는 생각이 들었음.
Dijkstra는 시작점 기준으로 인근 정점부터 접근해야 하는데, 나는 1~V+1 순서대로 접근을 해서 틀리지 않았을까 싶었음.
INF = int(1e9)
V,E = list(map(int,input().split()))
start = int(input())
answer = [INF for _ in range(V+1)]
answer[start] = 0
edges = { _ : [] for _ in range(1,V+1)}
for i in range(E):
temp = list(map(int,input().split()))
edges[temp[0]].append([temp[1],temp[2]])
for val in edges[start]:
answer[val[0]] = val[1]
for i in range(1,V+1):
for edge in edges[i]:
answer[edge[0]] = min(answer[edge[0]],answer[i]+edge[1])
for i in range(1,V+1):
if answer[i] == INF:
print('INF')
else:
print(answer[i])
나의 맞은 풀이
다른 분들의 풀이를 봤는데 Dijkstar알고리즘은 heapq를 사용하여 현재 시작 노드와 가까운 순으로 정렬되면 최단 거리 노드를 찾는 로직이 빠져도 되기 때문에 빠르다는 이야기가 있어서 시도해봤음
import heapq
import sys
def dijkstra(start):
q= []
heapq.heappush(q,(0,start))
answer[start] = 0
while q:
dist, now = heapq.heappop(q)
# 현재 저장된 값보다 가중치가 크면 바로 패스
if answer[now] < dist:
continue
#현재 노드와 연결된 인접 노드 확인
for i in edges[now]:
cost = dist+ i[1]
if cost < answer[i[0]] :
answer[i[0]] = cost
heapq.heappush(q,(cost,i[0]))
INF = int(1e9)
V,E = list(map(int,sys.stdin.readline().split()))
start = int(sys.stdin.readline())
answer = [INF for _ in range(V+1)]
answer[start] = 0
# edge값 저장
edges = { _ : [] for _ in range(1,V+1)}
for i in range(E):
temp = list(map(int,sys.stdin.readline().split()))
edges[temp[0]].append([temp[1],temp[2]])
dijkstra(start)
for i in range(1,V+1):
if answer[i] == INF:
print('INF')
else:
print(answer[i])
'알고리즘 문제 풀이 > 백준' 카테고리의 다른 글
[백준] 8진수 2진수 - python[ 구현 ] (0) | 2024.09.09 |
---|---|
[백준] 곱셈- python[ 구현 ] (0) | 2023.11.13 |
[백준] 평범한 배낭 - python[ dp ] (0) | 2023.10.31 |
[백준] 1로 만들기 - python[ DP ] (0) | 2023.10.30 |
백준 이중 우선순위 큐 - 7662 (0) | 2023.03.29 |