<aside> 🔥 이코테 3번 문제

</aside>

<aside> 🔥 문제 정리

첫째줄에 도시개수 n, 통로 개수 m, 시작점 c 가주어진다.

다음 m개의 줄에 시작 도시 x, 도착 도시 y, 비용 z가 주어진다.

c 도시에서 다른 모든도시로 메세지를 보내려고 할 때,

메세지를 받을 수 있는 도시는 몇개이고, 최대 비용은 얼마나 드는가를 출력하는 문제이다.

</aside>

<aside> 🔥 접근 방법

이 문제는 시작점에서 각 노드로 가는 최단거리를 찾으면 해결할 수 있을 것 같다.

플로이드 워셜보다는 다익스트라로 구현하는게 맞는거 같다.

</aside>

<aside> 🔥 코드 진행

입력값들을 받고 x, y, z로 그래프를 연결해준다. 그리고 다익스트르 알고리즘을 호출한다.

n, m, c = map(int, input().split())
graph = [[] for _ in range(n + 1)]
for _ in range(m):
    x, y, z = map(int, input().split())
    graph[x].append((y, z))

print(dijkstra(graph, c))

다음부터는 기본적인 힙을 이용한 다익스트라 알고리즘을 활용했다.

먼저 거리 테이블과 힙을 생성해서 힙에 (비용, 시작점)을 넣어 준다.

def dijkstra(graph, start):
    N = len(graph)

    # 거리 테이블 무한대로 초기화
    dist = [INF] * N

    # 힙 생성하여 (거리, 시작점) 넣기
    q = []
    heapq.heappush(q, (0, start))

    # 시작점은 거리비용 0부터 시작
    dist[start] = 0

힙에 값이 있는동안 반복하며 힙에서 가장 비용이 작은 노드 정보를 가져온다.

while q:
        # 힙에서 가장 비용이 적은 노드 정보 가져온다.
        acc, cur = heapq.heappop(q)

다음으로 이미 기록된게 더 비용이 적다면 건너뛰어준다. 어차피 답에 추가될 일 없기 때문이다.

# 이미 기록된게 현재 꺼내온 노드의 값보다 적다면 건너뛰기
if dist[cur] < acc:
    continue

현재 꺼낸 노드의 인접 노드와 그 인접노드의 비용을 가져온다.

이전 합계에 인접노드 비용을 더해 누적 합계를 계산하고 누적 합계가 기록된 것 보다 더 짧을 경우에는

업데이트를 해주고 힙에 넣어 다시 반복문을 돈다.

# 현재 꺼낸 노드의 그래프에서 인접 노드와 비용 정보 가져오기
for adj, d in graph[cur]:
    # 누적 합계 계산
    cost = acc + d

    # 인접노드로 거쳐온 비용이 더 짧은 경우
    if cost < dist[adj]:
        # 업데이트
        dist[adj] = cost
        heapq.heappush(q, (cost, adj))

마지막으로 정답처리를 해준다.

도시의 시작 개수를 -1로 잡아준 이유는 시작 노드는 제외해야하기 떄문이다.

만약 거리 테이블에서 무한대로 입력된 값이 있으면 메세지가 도달할 수 없기 때문에 카운트하지 않는다.

# 도시의 개수는 시작 노드는 제외.
    city_recieve_count = -1
    # 최대 거리 찾기
    max_cost = max(dist[1:])
    # 거리테이블에서 무한인 경우에는 도달할 수 없으므로 카운트 x
    for i in dist[1:]:
        if i != INF:
            city_recieve_count += 1
    print(dist)
    return city_recieve_count, max_cost

</aside>