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()

	list := make([][]int, n)
	weight := make([]int, n)
	for i := range list {
		list[i] = make([]int, n)
		weight[i] = NIL
		for j := range list[i] {
			list[i][j] = NIL
		}
	}

	for i := 0; i < n; i++ {
		u := scanInt()
		k := scanInt()
		for j := 0; j < k; j++ {
			v := scanInt()
			w := scanInt()
			list[u][v] = w
		}
	}

	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 i, w := range list[node.id] {
			if w == NIL {
				continue
			}
			heap.Push(h, Node{id: i, weight: w + node.weight})
		}
	}

	w := bufio.NewWriter(os.Stdout)
	for i := 0; i < n; i++ {
		fmt.Fprint(w, i)
		fmt.Fprint(w, " ")
		fmt.Fprint(w, weight[i])
		fmt.Fprintln(w)
	}
	w.Flush()
}

Python: from collections import namedtuple
import heapq

Edge = namedtuple('Edge', ('fr', 'to', 'cost'))
inf = int(1e9)


def bellman_ford(n, start, edges):
    dists = [inf for _ in range(n)]
    dists[start] = 0
    while True:
        updated = False
        for e in edges:
            if dists[e.fr] != inf and dists[e.fr] + e.cost < dists[e.to]:
                updated = True
                dists[e.to] = dists[e.fr] + e.cost

        if not updated:
            break

    return dists


def dijkstra(n, costs):
    dists = [inf for _ in range(n)]
    dists[0] = 0

    queue = []
    for (i, d) in enumerate(dists):
        heapq.heappush(queue, (d, i))

    while len(queue) > 0:
        d, i = heapq.heappop(queue)
        if d > dists[i]:
            continue

        for v in range(n):
            if v == i or costs[i][v] == inf:
                continue

            if dists[i] + costs[i][v] < dists[v]:
                dists[v] = dists[i] + costs[i][v]
                heapq.heappush(queue, (dists[v], v))

    return dists


def warshall_floyd(n, costs):
    dists = [[costs[i][j] if i != j else 0 for i in range(n)] for j in range(n)]

    for k in range(n):
        for i in range(n):
            for j in range(n):
                dists[i][j] = min(dists[i][j], dists[i][k] + dists[k][j])

    return dists


n = int(input())

m = [[inf for _ in range(n)] for _ in range(n)]
es = []
for i in range(n):
    fs = list(map(int, input().split()))
    ne = fs[1]
    for j in range(ne):
        v = fs[2+2*j]
        c = fs[2+2*j+1]
        m[i][v] = c
        es.append(Edge(i, v, c))


# d = bellman_ford(n, 0, es)
# d = dijkstra(n, m)
d = warshall_floyd(n, m)
for (i, di) in enumerate(d[0]):
    print(i, di)

Python: from heapq import *

#edge {to cost}
#P {mindirection, modeNum}
#G a list which contain informations of nodes

# building G from input
V=int(input())
G=[]
for _ in range(V):
    temp=list(map(int,input().split()))
    l=[]
    for i in range(1,temp[1]+1):
        l.append(temp[2*i:2*(i+1)])
    G.append(l)

que=[] #having the minimum distance
INF=1e8
d=[INF for i in range(V)] #having the distance
d[0]=0
heappush(que,[0,0])

while len(que)!=0:
    p=heappop(que)
    v=p[1]
    if(d[v]<p[0]):
        continue
    for i in range(len(G[v])):
        e=G[v][i]
        if(d[e[0]]>d[v]+e[1]):
            d[e[0]]=d[v]+e[1]
            heappush(que,[d[e[0]],e[0]])
            
for i in range(V):
    print(i,d[i])

Python: 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)]
for i in range(n):
    line = list(map(int, input().split(' ')))
    if line[1] == 0: continue
    for j in range(2, 2+2*line[1], 2):
        M[i][line[j]] = line[j+1]


colors = []
d = []
p = [-1 for i in range(n)]

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

    while True:
        mincost = INFTY
        for i in range(n):
            if colors[i] != Color.BLACK and d[i] < mincost:
                mincost = d[i]
                u = i

        if mincost == INFTY: break
        colors[u] = Color.BLACK

        for v in range(n):
            if colors[v] != Color.BLACK and M[u][v] != -1:
                if d[u] + M[u][v] < d[v]:
                    d[v] = d[u] + M[u][v]
                    p[v] = u
                    colors[v] = Color.GRAY

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

Python: #coding:utf-8
def Dijkestra(G,n):
    d=[100000000000]*n
    pi=[None]*n
    d[0]=0
    C=[]
    for i in range(n):
        C.append(i)
    
    while len(C)!=0:
        u=C[0]
        for i in range(1,len(C)):
            if d[u]>d[C[i]]:
                u=C[i]
        C.remove(u)
        for i in range(len(G[u])):
            if G[u][i]==-1:
                continue
            elif d[i]>d[u]+G[u][i]:
                d[i]=d[u]+G[u][i]
                pi[i]=u                
    for i in range(n):
        print(i,d[i])
    

if __name__=="__main__":
    n=int(input())
    G=[]
    for i in range(n):
        a=[]
        ele=list(map(int,input().split()))
        k=ele[1]
        t=ele[2:]
        v=c=[]
        for j in range(k):
            v=v+[t[2*j]]
            c=c+[t[2*j+1]]
        for j in range(n):
            if j in v:
                a.append(c[v.index(j)])
            else:
                a.append(-1)
        G.append(a)
    for i in range(n):
        print(G[i])
    Dijkestra(G,n)

Python: n = int(input())
INF = float("inf")
edges = [[] for _ in range(n)]
visited = [False]*n
# edges = [[INF for _ in range(n)] for _ in range(n)]
edges = [[] for _ in range(n) for _ in range(n)]
d = [INF]*n
d[0] = 0

for _ in range(n):
    ls = list(map(int, input().split()))
    u = ls[0]
    degrees = ls[1]
    data = ls[2:]
  
    for i in range(degrees):
        v = data[i*2]
        cost = data[i*2+1]
        edges[u].append((v, cost))
        # edges[u][v] = cost

#通常版
# for _ in range(n):
#     dmin = float("inf")
#     for i in range(n):
#         if not visited[i] and d[i] < dmin:
#             dmin = d[i]
#             u = i
#     visited[u] = True
#     for v, c in enumerate(edges[u]):
#         d[v] = min(d[v], d[u] + c)

# for i in range(n):
#     print(i, d[i])
    
#heap版
import heapq

heap = [(0, 0)]
d[0] = 0


while heap:
    du, u = heapq.heappop(heap)
    for v, cost in edges[u]:
        if du + cost < d[v]:
            d[v] = du +  cost
            heapq.heappush(heap, (d[v], v))

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

Python: from heapq import heappop, heappush 


if __name__ == '__main__':
	n = int(input())
	graph = [[-1]*n for i in range(n)]
	for i in range(n):
		node_data = list(map(int, input().split()))
		index = node_data[0]
		edge_num = node_data[1]
		node_list = node_data[2:]
		for i in range(edge_num):
			graph[index][node_list[i * 2]] = node_list[i * 2 + 1]

	cost_map = [-1 for i in range(n)]

	heap_q = []
	heap_q.append((0, 0))

	while len(heap_q) != 0:
		node = heappop(heap_q)
		cost = node[0]
		u = node[1]

		if cost_map[u] != -1:
			continue
		cost_map[u] = cost

		for v in range(n):
			if graph[u][v] != -1:
				heappush(heap_q, (graph[u][v] + cost, v))

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