Go: package main

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

type Node struct {
	Id int
	Dis int
}

type PriorityQueue []*Node

func (pq PriorityQueue) Len() int { return len(pq) }

func (pq PriorityQueue) Less(i, j int) bool {
	return pq[i].Dis < pq[j].Dis
}

func (pq PriorityQueue) Swap(i, j int) {
	pq[i], pq[j] = pq[j], pq[i]
}

func (pq *PriorityQueue) Push(x interface{}) {
	*pq = append(*pq, x.(*Node))
}

func (pq *PriorityQueue) Pop() interface{} {
	n := len(*pq)
	pop := (*pq)[n-1]
	*pq = (*pq)[0:n-1]
	return pop
}

func main() {
	var n int
	fmt.Scan(&n)

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

	g := make([][]int, n)
	c := make([][]int, n)
	pq := make(PriorityQueue, 0, n)
	d := make([]int, n)
	for i := 0; i < n; i++ {
		sc.Scan()
		u, _ := strconv.Atoi(sc.Text())
		sc.Scan()
		k, _ := strconv.Atoi(sc.Text())
		g[u] = make([]int, k)
		c[u] = make([]int, k)
		for j := 0; j < k; j++ {
			sc.Scan()
			g[u][j], _ = strconv.Atoi(sc.Text())
			sc.Scan()
			c[u][j], _ = strconv.Atoi(sc.Text())
		}

		if u == 0 {
			d[u] = 0
		} else {
			d[u] = 1 << 30
		}
		pq.Push(&Node{u, d[u]})
	}
	heap.Init(&pq)

	for pq.Len() > 0 {
		node := heap.Pop(&pq).(*Node)
		for i := 0; i < len(g[node.Id]); i++ {
			nextId := g[node.Id][i]
			nextDis := node.Dis + c[node.Id][i]
			if nextDis < d[nextId] {
				d[nextId] = nextDis
				heap.Push(&pq, &Node{nextId, nextDis})
			}
		}
	}

	wr := bufio.NewWriter(os.Stdout)
	for i := 0; i < n; i++ {
		wr.WriteString(strconv.Itoa(i))
		wr.WriteString(" ")
		wr.WriteString(strconv.Itoa(d[i]))
		wr.WriteString("\n")
	}
	wr.Flush()
}

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
D_MAX = int(5e10 + 1)


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
    path_list[init_vertex_index] = 0
    path_heap = []
    # heapq: rank by tuple[0], at here it's d[u]
    hp.heappush(path_heap, (0, init_vertex_index))

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

        color[current_vertex] = BLACK

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

    return path_list


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

    parent_list, path_list = [-1] * vertices_num, [D_MAX] * vertices_num
    color = [WHITE] * vertices_num
    init_adj_table = tuple(dict() for _ in range(vertices_num))
    init_vertex_index = 0

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

Python: import heapq as hq

n=int(input())
da=[[] for i in range(n)]
for i in range(n):
    li=list(map(int,input().split()))
    for i in range(li[1]):
        da[li[0]].append([li[i*2+3],li[i*2+2]])
q=[]
ans=[-1 for i in range(n)]
ans[0]=0
for i in da[0]:
    hq.heappush(q,i)
while len(q)!=0:
    no=hq.heappop(q)
    if ans[no[1]] < 0:
        ans[no[1]]=no[0]
        for i in da[no[1]]:
            hq.heappush(q,[no[0]+i[0],i[1]])
for i in range(n):
    print("{} {}".format(i,ans[i]))

Python: import sys

f_i = sys.stdin

n = int(f_i.readline())

adj = [[]] * n
for x in f_i:
    x = list(map(int, x.split()))
    adj[x[0]] = [c_v for c_v in zip(x[3::2], x[2::2])]

import heapq

def dijkstra():
    PQ = [(0, 0)]
    isVisited = [False] * n
    distance = [999900001] * n

    distance[0] = 0
    
    while PQ:
        uc, u = heapq.heappop(PQ)

        if uc <= distance[u]:
            isVisited[u] = True
        
            for vc, v in adj[u]:
                if isVisited[v] == False:
                    t_cost = distance[u] + vc
                    if t_cost < distance[v]:
                        distance[v] = t_cost
                        heapq.heappush(PQ, (t_cost, v))

    for v, d in enumerate(distance):
        print(v, d)


dijkstra()

Python: import sys
import heapq
n = int(input())
V = [[int(i) for i in input().split()] for _ in range(n)]
dis = [sys.maxsize for _ in range(n)]
dis[0] = 0
h = []
for i in range(n):
    heapq.heappush(h,(dis[i],i))
while(len(h)>0):
    node = heapq.heappop(h)
    tmp = node[1]
    for i in range(V[tmp][1]):
        ind = V[tmp][2*i+2]
        cos = V[tmp][2*i+3]
        if cos + dis[tmp] < dis[ind]:
            dis[ind] = cos + dis[tmp]
            heapq.heappush(h,(dis[ind],ind))
for i,j in enumerate(dis):
    print(i,j)

Python: from heapq import heappop, heappush
import sys


class SSSP:
    """Given weighted graph, find Single Sorce Shortest Path from node 0.

    >>> st = SSSP([[(2, 3), (3, 1), (1, 2)], \
                   [(0, 2), (3, 4)], \
                   [(0, 3), (3, 1), (4, 1)], \
                   [(2, 1), (0, 1), (1, 4), (4, 3)], \
                   [(2, 1), (3, 3)]])
    >>> [st.weight(n) for n in range(5)]
    [0, 2, 2, 1, 3]
    """
    def __init__(self, graph):
        self.size = len(graph)
        self.tree = []
        self.weights = [-1] * self.size
        self._search(graph)

    def weight(self, n):
        return self.weights[n]

    def _search(self, graph):
        h = []
        self.weights[0] = 0
        count = 1
        for i, w in graph[0]:
            heappush(h, (w, 0, i))

        while count < self.size:
            while len(h) > 0:
                weight, src, dst = heappop(h)
                if self.weights[dst] < 0:
                    self.weights[dst] = weight
                    count += 1
                    self.tree.append((src, dst))
                    for i, w in graph[dst]:
                        if self.weights[i] < 0:
                            heappush(h, (w+weight, dst, i))
                    break


def run():
    n = int(input())

    nodes = [None] * n
    for line in sys.stdin:
        id_, deg, *edges = [int(i) for i in line.split()]
        nodes[id_] = []
        for _ in range(deg):
            tgt, wgt, *edges = edges
            nodes[id_].append((tgt, wgt))

    st = SSSP(nodes)
    for node in range(n):
        print('{} {}'.format(node, st.weight(node)))


if __name__ == '__main__':
    run()

Python: from heapq import heappush, heappop

inf = float('inf')
n = int(input())
g = []
for i in range(n):
    line = list(map(int, input().split()[2:]))
    g.append(zip(line[0::2], line[1::2]))

dist = [inf] * n
dist[0] = 0
heap = [(0, 0)]

while heap:
    current = heappop(heap)[1]
    for v, c in g[current]:
        new_dist = dist[current] + c
        if new_dist < dist[v]:
            dist[v] = new_dist
            heappush(heap, (new_dist, v))

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