Go: package main

import (
	"bufio"
	"container/heap"
	"fmt"
	"os"
	"strconv"
)

const NIL = -1

type Node struct {
	id     int
	weight int
}

func init() {
	sc.Split(bufio.ScanWords)
}

type NodeHeap []Node

func (h NodeHeap) Len() int           { return len(h) }
func (h NodeHeap) Less(i, j int) bool { return h[i].weight < h[j].weight }
func (h NodeHeap) Swap(i, j int)      { h[i], h[j] = h[j], h[i] }

func (h *NodeHeap) Push(x interface{}) {
	*h = append(*h, x.(Node))
}

func (h *NodeHeap) Pop() interface{} {
	old := *h
	n := len(old)
	x := old[n-1]
	*h = old[0 : n-1]
	return x
}

var sc = bufio.NewScanner(os.Stdin)

func scanInt() int {
	num, _ := strconv.Atoi(scanString())
	return num
}

func scanString() string {
	sc.Scan()
	return sc.Text()
}

func init() {
	sc.Split(bufio.ScanWords)
}

func main() {
	n := scanInt()

	route := make([][]Node, n)
	weight := make([]int, n)
	for i := 0; i < n; i++ {
		weight[i] = NIL
	}

	for i := 0; i < n; i++ {
		u := scanInt()
		k := scanInt()
		route[i] = make([]Node, k)
		for j := 0; j < k; j++ {
			route[u][j] = Node{id: scanInt(), weight: scanInt()}
		}
	}

	start := Node{id: 0, weight: 0}
	h := &NodeHeap{start}
	heap.Init(h)

	for h.Len() > 0 {
		node := heap.Pop(h).(Node)
		if weight[node.id] != NIL {
			continue
		}
		weight[node.id] = node.weight

		for _, nextNode := range route[node.id] {
			if weight[nextNode.id] != NIL {
				continue
			}
			nextNode.weight += node.weight
			heap.Push(h, nextNode)
		}
	}

	for i, w := range weight {
		fmt.Println(i, w)
	}
}

Python: #!/usr/bin/env python
# -*- coding: utf-8 -*-

"""
input:
5
0 3 2 3 3 1 1 2
1 2 0 2 3 4
2 3 0 3 3 1 4 1
3 4 2 1 0 1 1 4 4 3
4 2 2 1 3 3

output:
0 0
1 2
2 2
3 1
4 3
"""

import sys
import heapq as hp

WHITE, GRAY, BLACK = 0, 1, 2


def generate_adj_table(v_table):
    for each in v_table:
        v_index, v_adj_length, *v_adj_list = map(int, each)
        # assert len(v_adj_list) == v_adj_length * 2
        for pair in zip(v_adj_list[::2], v_adj_list[1::2]):
            init_adj_table[v_index][pair[0]] = pair[1]

    return init_adj_table


def dijkstra_path_heap():
    # path search init
    distance[init_vertex] = 0
    path_heap = []
    # heapq: rank by tuple[0], at here it's d[u]
    hp.heappush(path_heap, (0, init_vertex))

    while path_heap:
        current_vertex = hp.heappop(path_heap)[1]

        color[current_vertex] = BLACK

        for adj_vertex, adj_weight in adj_table[current_vertex].items():
            if color[adj_vertex] is not BLACK:
                # alt: d[u] + w[u,v]
                alt_path = distance[current_vertex] + adj_weight
                if alt_path < distance[adj_vertex]:
                    # update path_list
                    distance[adj_vertex] = alt_path
                    # update heap
                    hp.heappush(path_heap, (alt_path, adj_vertex))
                    color[adj_vertex] = GRAY

    return distance


if __name__ == '__main__':
    _input = sys.stdin.readlines()
    vertices_num = int(_input[0])
    init_vertices_table = map(lambda x: x.split(), _input[1:])
    # assert len(init_vertices_table) == vertices_num

    distance = [float('inf')] * vertices_num
    color = [WHITE] * vertices_num
    init_adj_table = tuple(dict() for _ in range(vertices_num))
    init_vertex = 0

    adj_table = generate_adj_table(init_vertices_table)
    ans = dijkstra_path_heap()
    for i, v in enumerate(ans):
        print(i, v)

Python: def dijkstra(n):
    inf = 10 ** 6 + 1
    dist = [0] + [inf] * (n - 1)
    visited = [False] * n

    while not all(visited):
        dmin = inf
        for i, (d, v) in enumerate(zip(dist, visited)):
            if v:
                continue
            elif dmin > d:
                dmin, u = d, i
        visited[u] = True
        for (v, c) in edge[u]:
            if dist[v] > dist[u] + c:
                dist[v] = dist[u] + c
    return dist

n = int(input())
edge = [[]] * n
for _ in range(n):
    l = list(map(int, input().split()))
    edge[l[0]] = (e for e in zip(l[2::2], l[3::2]))
for i, c in enumerate(dijkstra(n)):
    print(i, c)

Python: import sys
input = sys.stdin.buffer.readline

import heapq

#点の数が10**5のオーダー以下で使える
#頂点sからの各頂点への最短距離を出力
def dijkstra(s, n, edge): #s:始点、n:頂点の数、edge:重み付き辺の配列（edge[i]:iから出る[重み、行き先]の配列)
    INF = 10**20
    d = [INF]*n # d[i]: sと点iとの距離
    used = [True]*n #Trueは未確定
    d[s] = 0 #初期条件
    used[s] = False # 初期条件
    edge_list = []
    for a, b in edge[s]:
        heapq.heappush(edge_list, a*(10**6)+b) #heapqの中に重みと辺の抱き合わせた情報を入れる
    while len(edge_list):
        min_edge = heapq.heappop(edge_list) #まだ使われていない頂点の中から最小の重みのものを取りだす
        if not used[min_edge%(10**6)]: # 確定していたらcontinue、確定していない時のみ以下の処理を行う
            continue
        v = min_edge%(10**6) #行き先の情報を復元
        d[v] = min_edge // (10**6) #重みの情報を復元し、sとvの最短距離d[v]を更新する
        used[v] = False
        for e in edge[v]:
            if used[e[1]]: #その行き先がまだ未確定の場合
                heapq.heappush(edge_list, (e[0]+d[v])*(10**6) + e[1])
        
    return d


n = int(input())

edge = [[] for _ in range(n)] # edge:重み付き辺の配列（edge[i]:iから出るtuple(重み、行き先)の配列)
for _ in range(n):
    x, y, *li = list(map(int, input().split()))
    for i in range(y):
        edge[x].append((li[2*i+1], li[2*i]))
        #edge[li[2*i]].append([li[2*i+1], x]) # 無向グラフのとき

d = dijkstra(0, n, edge)

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

Python: from queue import PriorityQueue
 
INF=1<<30
n=int(input())
adj=[[]for i in range(n+1)]
maxx = 10010

def dijkstra():
    global adj
    PQ=PriorityQueue()
      
    d=[INF for i in range(n)]
    #p=[-1 for i in range(n)]
    flag=[0 for i in range(n)]
 
    d[0] = 0;
    PQ.put((0, 0))
    while (not PQ.empty()):
        f = PQ.get()
        u = f[1]
        
        # 标记已经加入S
        flag[u] = 1

        #如果不是最小最短路径则忽略
        #if (d[u] >f[0] ):
            #continue
        lens = len(adj[u])
        for j in range(lens):
            v = adj[u][j][0]
            if (flag[v] == 0 and d[v] > d[u] + adj[u][j][1]):
                d[v] = d[u] + adj[u][j][1]
                PQ.put((d[v], v));
            

    for i in range(n):
        if d[i]==INF:
            print("%d %d"%(i, -1))
        else:
            print("%d %d"%(i, d[i]))
        

for i in range(n):
    s=[int(x) for x in input().split()]
    u=s[0]
    k=s[1]
    for j in range(k):
        adj[u].append((s[j*2+2],s[2*j+3]))
 
dijkstra()