# Coding/# 백준

[백준 / 1753] 최단경로 - Python

강현들 2021. 3. 18. 13:37
728x90
반응형

시간 초과와 여러개의 간선에서 문제가 있었다.

 

최단 경로는 '다익스트라(Dijkstra) 알고리즘'을 먼저 공부해야 한다.

↳ 출발 지점으로부터 비용(가중치)이 가장 낮은 경로를 계산

 

2021.03.18 - [# Coding/# Algorithm] - [보기 쉬운 Algorithm] 다익스트라(Dijkstra) 알고리즘 - Python

 

[보기 쉬운 Algorithm] 다익스트라(Dijkstra) 알고리즘 - Python

'다익스트라(Dijkstra) 알고리즘'은 비용(가중치) 간선이 있는 노드 그래프의 최단 거리를 구하는 알고리즘 시간을 줄이기 위해서 파이썬 모듈 중 최소 힙을 구현할 수 있는 heapq를 사용한다. ↳ list

joinmycode.tistory.com

<다익스트라 알고리즘>

 

import sys
import heapq

def dijkstra(graph, start):
    distances = {node: float('INF') for node in graph}
    distances[start] = 0
    queue = []
    heapq.heappush(queue, [distances[start], start])

    while queue:
        current_distance, node = heapq.heappop(queue)

        if distances[node] < current_distance:
            continue

        for new_node, new_distance in graph[node].items():
            distance = new_distance+current_distance
            if distance < distances[new_node]:
                distances[new_node] = distance
                heapq.heappush(queue, [distance, new_node])

    return distances

 

입력 시간과 알고리즘 시간을 줄이기 위해서 sys와 heqpq를 import한다.

distances - {노드 : 최단거리} 

distances[start]는 계산 되면 안되므로 0으로 만들어 준다.

queue에는 현재 기준 노드와 그 노드까지 온 거리가 들어간다.

 

queue에 값이 없을 때 까지 반복한다.

현재 기준 노드와 그 현재 노드까지의 비용(가중치)를 받아온다.

distances에 있는 거리보다 길면 무시한다.

 

짧을 경우 graph에 있는 현재 노드에서 갈 수 있는 노드와 비용(가중치)을 받아온다.

다음 노드의 길이를 구하기 위해서 현재 노드 길이와 앞으로의 노드 길이를 더해준다.

그 길이가 distances에 있는 값보다 짧을 경우 값을 바꿔준다.

그리고 queue에 다음 노드와 다음 노드까지 가는데 걸린 길이를 넣어준다.

 

distances에 모든 노드의 최소 값이 담겨 있으므로 반환해준다.

 

<입력1>

 

V, E = map(int, sys.stdin.readline().split())
K = int(sys.stdin.readline())

 

V(node 개수), E(간선 개수), K(출발점) 변수를 입력받는다.

<그래프 선언>

 

graph = {}
for i in range(1, V+1):
    graph[i] = {}

 

간선이 없는 노드도 있을 수 있으니, 모든 노드를 그래프에 추가해준다.

 

<입력2>

for _ in range(E):
    u, v, w = map(int, sys.stdin.readline().split())
    
    if v in graph[u]:
        if graph[u][v] > w:
            graph[u][v] = w
    else:
        graph[u][v] = w

 

간선의 개수(E)만큼 입력을 받는다.

문제에 노드 사이에 여러 간선이 있을 수 있으니 중복 간선에서 가장 비용(가중치)가 낮은 값만 저장한다.

if문에서는 그래프에 u노드에 v로 가는 간선이 없으면 새로 추가해주고(else), 이미 선이 존재하는 경우 더 낮은 값을 저장해준다.

 

<계산과 출력>

 

distances = dijkstra(graph, K)

for i in distances:
    print(distances[i] if distances[i] != float('INF') else 'INF')

 

함수의 최단 거리 반환 값을 distances에 대입한다.

경로가 존재 하지 않는 경우 inf 소문자로 출력되므로 대문자 INF로 출력되게 한다.

 

<전체 코드>

 

import sys
import heapq


def dijkstra(graph, start):
    distances = {node: float('INF') for node in graph}
    distances[start] = 0
    queue = []
    heapq.heappush(queue, [distances[start], start])

    while queue:
        current_distance, node = heapq.heappop(queue)

        if distances[node] < current_distance:
            continue

        for new_node, new_distance in graph[node].items():
            distance = new_distance+current_distance
            if distance < distances[new_node]:
                distances[new_node] = distance
                heapq.heappush(queue, [distance, new_node])

    return distances


V, E = map(int, sys.stdin.readline().split())
K = int(sys.stdin.readline())

graph = {}
for i in range(1, V+1):
    graph[i] = {}

for _ in range(E):
    u, v, w = map(int, sys.stdin.readline().split())

    if v in graph[u]:
        if graph[u][v] > w:
            graph[u][v] = w
    else:
        graph[u][v] = w

distances = dijkstra(graph, K)

for i in distances:
    print(distances[i] if distances[i] != float('INF') else 'INF')
728x90
반응형