Go: package main

import (
	"bufio"
	"fmt"
	"os"
	"strconv"
)

const BIG_COST = 200000

type Path struct {
	node int
	cost int
}

func main() {
	sc := bufio.NewScanner(os.Stdin)
	sc.Split(bufio.ScanWords)

	nNodes := scanInt(sc)

	// 各頂点につながる頂点一覧を得るための隣接リスト
	graph := make([][]Path, nNodes)

	for i := 0; i < nNodes; i++ {
		u := scanInt(sc)
		k := scanInt(sc)
		graph[i] = make([]Path, k)
		for d := 0; d < k; d++ {
			graph[u][d] = Path{
				node: scanInt(sc),
				cost: scanInt(sc),
			}
		}
	}

	// 0 から各頂点への最小コストを保存する配列
	minCosts := make([]int, nNodes)

	minCosts[0] = 0
	for i := 1; i < nNodes; i++ {
		minCosts[i] = BIG_COST
	}

	// 各頂点が調査済みかどうかを保持する配列
	checked := make([]bool, nNodes)

	// 最小コストのパスを高速に取得するためのヒープ。
	// コストが小さいものほどルートに来るようにする。
	heap := NewHeap(func(a, b Path) bool {
		return a.cost < b.cost
	})

	heap.insert(Path{node: 0, cost: 0})
	for heap.size > 0 {
		u := heap.extractMax()

		// 隣接行列を使っていた時とは違い、ヒープには
		// 同じノードへのパスが複数含まれうる。そのため既によりコストの低い
		// パスが見つかっている場合は無視する。
		if minCosts[u.node] < u.cost {
			continue
		}

		checked[u.node] = true

		for _, v := range graph[u.node] {
			cost := v.cost + u.cost
			if !checked[v.node] && cost < minCosts[v.node] {
				minCosts[v.node] = cost
				heap.insert(Path{node: v.node, cost: cost})
			}
		}
	}

	w := bufio.NewWriter(os.Stdout)
	for i, cost := range minCosts {
		fmt.Fprintf(w, "%d %d\n", i, cost)
	}
	w.Flush()
}

func scanInt(sc *bufio.Scanner) int {
	sc.Scan()
	v, _ := strconv.Atoi(sc.Text())
	return v
}

// --- From ALDS1_9_C: Priority Queue

type Heap struct {
	size   int
	heap   []Path
	isHigh func(a, b Path) bool
}

func NewHeap(isHigh func(a, b Path) bool) Heap {
	heap := make([]Path, 1) // 先頭は不使用
	return Heap{size: 0, heap: heap, isHigh: isHigh}
}

func (h *Heap) insert(v Path) {
	h.size += 1
	if h.size > len(h.heap)-1 {
		h.heap = append(h.heap, v)
	} else {
		h.heap[h.size] = v
	}

	for i := h.size; i > 1; {
		parent := i / 2
		if h.isHigh(h.heap[parent], h.heap[i]) {
			break
		}
		h.heap[i], h.heap[parent] = h.heap[parent], h.heap[i]
		i = parent
	}
}

func (h *Heap) extractMax() Path {
	if h.size <= 0 {
		panic("cannot extract from empty heap")
	}

	max := h.heap[1]
	h.heap[1] = h.heap[h.size]
	h.size -= 1
	h.maxHeapify(1)

	return max
}

func (h *Heap) maxHeapify(idx int) {
	left := idx * 2
	right := left + 1
	largest := idx

	if left <= h.size {
		if h.isHigh(h.heap[left], h.heap[idx]) {
			largest = left
		}
		if right <= h.size && h.isHigh(h.heap[right], h.heap[largest]) {
			largest = right
		}
	}

	if largest != idx {
		h.heap[idx], h.heap[largest] = h.heap[largest], h.heap[idx]
		h.maxHeapify(largest)
	}
}

Python: import sys
readline = sys.stdin.readline
from heapq import heapify, heappush, heappop
INF = float("inf")
def MAIN():
    n = int(input())
    adj = [[]] * n
    for _ in range(0, n):
        U = list(map(int, input().split()))
        adj[U[0]] = zip(U[2::2], U[3::2])
    def dijkstra():
        d = [0] + [INF] * (n - 1)
        hq = [(0, 0)]
        while hq:
            u = heappop(hq)[1]
            for v, c in adj[u]:
                alt = d[u] + c
                if d[v] > alt:
                    d[v] = alt
                    heappush(hq, (alt, v))
        print("\n".join(f"{i} {c}" for i, c in enumerate(d)))
    dijkstra()
MAIN()

Python: from sys import stdin
import heapq
INF = 1<<21
n = int(stdin.readline())
adj = [[]] * n
for u in range(0, n):
    U = list(map(int, stdin.readline().split()[2:]))
    adj[u] = [e for e in zip(U[0::2], U[1::2])]
def dijkstra():
    d = [0] + [INF] * (n - 1)
    hq = [(0, 0)]
    while hq:
        u = heapq.heappop(hq)[1]
        for v, c in adj[u]:
            alt = d[u] + c
            if d[v] > alt:
                d[v] = alt
                heapq.heappush(hq, (alt, v))
    for i, c in enumerate(d):
        print(i, c)
dijkstra()

Python: import sys

def dijkstra(v_count: int, edges: list, start: int,
             *, adj_matrix: bool = False, unreachable=float("inf")) -> list:
    """ ダイクストラ法
    :param v_count: 頂点数
    :param edges: 辺のリスト(隣接リストor隣接行列)
    :param start: スタートする頂点
    :param adj_matrix: edgesに渡したリストが隣接行列ならTrue
    :param unreachable: 到達不能を表すコスト値
                        隣接行列の辺の有無の判定および返すリストの初期値に使用
    """
    from heapq import heappush, heappop

    vertices = [unreachable] * v_count
    vertices[start] = 0
    q, rem = [(0, start)], v_count - 1

    while q and rem:
        cost, v = heappop(q)
        if vertices[v] < cost:
            continue
        rem -= 1

        dests = (filter(lambda x: x[1] != unreachable, enumerate(edges[v]))
                 if adj_matrix else edges[v])

        for dest, _cost in dests:
            newcost = cost + _cost
            if vertices[dest] > newcost:
                vertices[dest] = newcost
                heappush(q, (newcost, dest))

    return vertices

n = int(input())
edges = [[] for _ in [0]*n]
for a in (tuple(map(int, l.split())) for l in sys.stdin):
    edges[a[0]] = tuple(zip(a[2::2], a[3::2]))
vertices = dijkstra(n, edges, 0)
for i, n in enumerate(vertices):
    print(i, n)

Python: from heapq import heappush, heappop
from enum import Enum, auto

INFTY = float('inf')

class Color(Enum):
    WHITE = auto()
    GRAY = auto()
    BLACK = auto()

n = int(input())
M = [[-1 for i in range(n)] for i in range(n)]
adj_list = []
for i in range(n):
    u, k, *kv = list(map(int, input().split(' ')))
    if k == 0: continue
    adj_list.append(kv)
    for j in range(0,2*k,2):
        M[i][kv[j]] = kv[j+1]
colors = []
d = []

def dijkstra(s):
    global d
    colors = [Color.WHITE for i in range(n)]
    d = [INFTY for i in range(n)]
    pque = []
    d[0] = 0

    heappush(pque, (0, s))

    while len(pque) >= 1:
        vert_u = heappop(pque)
        u = vert_u[1]
        colors[u] = Color.BLACK
        if d[u] < vert_u[0]: continue
        i = 0
        while i <= len(adj_list[u])-2:
            v = adj_list[u][i]
            if colors[v] != Color.BLACK:
                if d[u] + adj_list[u][i+1] < d[v]:
                    d[v] = d[u] + adj_list[u][i+1]
                    colors[v] = Color.GRAY
                    heappush(pque, (d[v], v))
            i += 2

dijkstra(0)
for i in range(n):
    print(i, d[i])

Python: from heapq import heapify, heappush, heappop
INF = float("inf")
def MAIN():
    n = int(input())
    G = [[i, INF] for i in range(n)]
    G[0][1] = 0
    m = {}
    for _ in range(n):
        A = list(map(int, input().split()))
        m[A[0]] = {}
        for i in range(2, len(A), 2):
            m[A[0]][A[i]] = A[i + 1]
    dp = [(0, 0)]
    while dp:
        cost, u = heappop(dp)
        for v, c in m[u].items():
            if G[v][1] > G[u][1] + c:
                G[v][1] = G[u][1] + c
                heappush(dp, (G[v][1], v))
    print("\n".join(" ".join(map(str, a)) for a in G))
MAIN()

Python: import sys
readline = sys.stdin.readline
from heapq import heapify, heappush, heappop
INF = float("inf")
def MAIN():
    n = int(input())
    adj = [[]] * n
    for _ in range(0, n):
        U = list(map(int, input().split()))
        adj[U[0]] = zip(U[2::2], U[3::2])
    def dijkstra():
        d = [0] + [INF] * (n - 1)
        hq = [(0, 0)]
        while hq:
            u = heappop(hq)[1]
            for v, c in adj[u]:
                alt = d[u] + c
                if d[v] > alt:
                    d[v] = alt
                    heappush(hq, (alt, v))
        print("\n".join(f"{i} {c}" for i, c in enumerate(d)))
    dijkstra()
MAIN()