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: n = int(input())
ukvc = [ list(map(int,input().split())) for _ in range(n) ]

g = [ [] for _ in range(n) ]
for i in range(n):
    ls = ukvc[i]
    u = ls[0]
    k = ls[1]
    vc = ls[2:]
    for j in range(k):
        v = vc[2*j]
        c = vc[2*j+1]
        g[u].append([c,v])
# print(g)


# Dijkstra法(O(ElogV))
# edge[i] : iから出る道の[重み,行先]の配列
import heapq
def dijkstra_heap(s,edge):
    #始点sから各頂点への最短距離
    d = [float("inf")] * n
    used = [True] * n # True:未確定
    d[s] = 0
    used[s] = False
    edgelist = []
    for e in edge[s]:
        heapq.heappush(edgelist,e)
    while len(edgelist):
        minedge = heapq.heappop(edgelist)
        #まだ使われてない頂点の中から最小の距離のものを探す
        if not used[minedge[1]]:
            continue
        v = minedge[1]
        d[v] = minedge[0]
        used[v] = False
        for e in edge[v]:
            if used[e[1]]:
                heapq.heappush(edgelist,[e[0]+d[v],e[1]])
    return d

d = dijkstra_heap(0,g)

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

Python: import heapq


class Graph(object):

    class Node:
        def __init__(self, dist: int, number: int):
            self.dist = dist
            self.number = number

        def __lt__(self, other):
            return self.dist < other.dist \
                   or (self.dist == other.dist
                       and self.number < other.number)

        def __le__(self, other):
            return self.dist <= other.dist

        def __gt__(self, other):
            return other <= self

        def __ge__(self, other):
            return other < self

        def __str__(self):
            return "Node: (" + str(self.number) + ", " \
                   + str(self.dist) + ")"

    class Edge:
        def __init__(self, to: int, cost: int):
            self.to = to
            self.cost = cost

        def __str__(self):
            return "Edge: (" + str(self.to) + ", " \
                   + str(self.cost) + ")"

    INF = 10e10

    def __init__(self, node_n: int, start: int):
        self.node_n = node_n
        self.start = start
        self.edges = [{} for _ in range(self.node_n)]
        self.dist = [self.INF for _ in range(self.node_n)]

    def set_edge(self, from_pos: int, to_pos: int, cost: int, reversible: bool) -> None:
        self.edges[from_pos][to_pos] = (self.Edge(to_pos, cost))
        if reversible:
            self.edges[to_pos][from_pos] = (self.Edge(from_pos, cost))

    def solve(self) -> list:
        raise NotImplementedError


class Dijkstra(Graph):
    hq = []
    prev: list

    def __init__(self, node_n: int, start: int):
        super(Dijkstra, self).__init__(node_n, start)
        self.dist[self.start] = 0
        self.prev = [None for _ in range(node_n)]

    def solve(self) -> list:
        heapq.heappush(self.hq, self.Node(0, self.start))

        while len(self.hq) != 0:
            node = heapq.heappop(self.hq)
            if node.dist > self.dist[node.number]:
                continue

            for edge in self.edges[node.number].values():
                alt = self.dist[node.number] + edge.cost
                if self.dist[edge.to] > alt:
                    self.dist[edge.to] = alt
                    self.prev[edge.to] = node.number
                    heapq.heappush(self.hq, self.Node(self.dist[edge.to], edge.to))

        return self.dist


if __name__ == '__main__':
    n = int(input())
    graph = Dijkstra(n, 0)

    for _ in range(n):
        buff = list(map(int, input().split()))
        u = buff[0]
        k = buff[1]
        for i in range(k):
            graph.set_edge(u,
                           buff[2 + i * 2],
                           buff[3 + i * 2],
                           False)
    dist = graph.solve()
    for i, d in enumerate(dist):
        print(i, d)

Python: inf = float("inf")
n = int(input())
M = [[inf for i in range(n)] for i in range(n)]
for i in range(n):
    L = list(map(int, input().split()))
    for j in range(L[1]):
        M[L[0]][L[2 * j + 2]] = L[2 * j + 3]


def dijkstra(s):
    color = [0] * n
    d = [inf] * n
    d[s] = 0

    while True:
        mincost = inf
        for i in range(n):
            if color[i] !=1 and d[i] < mincost:
                mincost = d[i]
                u = i
        if mincost == inf: break
        color[u] = 1
        for v in range(n):
            if color[v] != 1 and M[u][v] != inf:
                if d[u] + M[u][v] < d[v]:
                    d[v] = d[u] + M[u][v]

    return d

d = dijkstra(0)
for i,v in enumerate(d):
 print("{} {}".format(i,v))

Python: class Graph:
    def __init__(self,V,E):
        self.V = V
        self.E = E

    def WF(self,st):
        N,INF = len(self.V),10**7+1
        dp = [INF for _ in range(N)]
        #dp[i]:頂点stから頂点iへの最小距離
        dp[st] = 0
        update = True
        while update:
            update = False
            for i in range(N):
                for j in range(N):
                    if (j,i) in self.E:
                        if dp[i] > dp[j] + self.E[(j,i)]:
                            dp[i] = dp[j] + self.E[(j,i)]
                            update = True
        return dp

def main():
    n = int(input())
    I = [list(map(int,input().split())) for _ in range(n)]
    V = set([i for i in range(n)])
    E = {}
    for i in range(n):
        for j in range(I[i][1]):
            E[(I[i][0],I[i][j*2+2])] = I[i][j*2+3]
    G = Graph(V,E)
    sp = G.WF(0)
    for i in range(n):
        print(i,sp[i])

if __name__ == "__main__":
    main()