白駿18352|特定距離の都市を探す(Dijkstra)


質問元:https://www.acmicpc.net/problem/18352
質問する
  • 1~nまでの都市とm本の一方向道路は1である.
  • 特定の都市xから出発し、到達可能なすべての都市のうち、
  • これはプログラムを書く問題で、最も短い
  • キロの都市の番号を見つけようとしています.
  • 入力
  • n:都市数(2<=n<=300000)
  • m:道路個数(1<=m<=10000)
  • k:距離情報(1<=k<=300000)
  • x:出発都市番号(1<=x
  • mの一方向都市情報(a b,aからbへの一方向道路あり)
  • 問題の処理方法
  • 優先キューのマルチアウトレットアルゴリズムを用いて、
    x番都市から他のすべての都市への最短パスを距離リストに保存します.
    distanceリストを用いてx番都市から距離kの都市までの番号を出力する.
  • 多翼点アルゴリズムを学習すると,特に応用はなく,多翼点アルゴリズムで解くことができる.
  • コード#コード#
    import sys
    import heapq
    
    # n : 도시 개수, m : 도로의 개수, k : 거리 정보, x : 출발 도시 번호
    n, m, k, x = map(int, sys.stdin.readline().split())
    
    # 간선 정보 2차원 리스트에 저장, 
    # 모든 도시의 거리는 1 만큼 떨어져있으므로 그래프에 가중치는 1만큼 설정한다.
    graph = [[] for _ in range(n + 1)]
    for _ in range(m):
        a, b = map(int, sys.stdin.readline().split())
        graph[a].append((b, 1))
    
    # 최단 거리 테이블 모두 무한으로 초기화
    INF = int(1e9)
    distance = [INF] * (n + 1)
    
    # Dijkstra 알고리즘
    def dijkstra(start):
        # 시작노드로 가는 최단 경로는 0으로 설정, 힙에 삽입
        distance[start] = 0
        heap = []
        heapq.heappush(heap, (0, start))
    
        while heap:
            # 최소힙을 이용하여 최단 거리가 가장 짧은 노드 정보 꺼내기
            dist, now = heapq.heappop(heap)
    
            # 현재 노드가 처리된적이 있다면 무시
            if distance[now] < dist:
                continue
    
            # 현재 노드와 다른 인접한 노드들을 확인
            for i in graph[now]:
                cost = dist + i[1]
    
                if cost < distance[i[0]]:
                    distance[i[0]] = cost
                    heapq.heappush(heap, (cost, i[0]))
    
    # 다익스트라 알고리즘을 실행
    # x에서 출발하여 n번 도시에 가는데 필요한 최단 거리 테이블 갱신
    dijkstra(x)
    
    # 도달할 수 없는 도시 체크를 위한 flag 변수 선언
    flag = False
    
    # 최단 경로 테이블을 돌면서 거리가 k인 도시 번호 출력
    for i in range(1, n + 1):
        if distance[i] == k:
            flag = True
            print(i)
    
    if flag == False:
        print(-1)
        
    参考資料
  • (Youtube)Donbina-最短パスアルゴリズム