Go: package main

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

// I/O
type Scanner struct {
	sc *bufio.Scanner
}

func NewScanner() *Scanner {
	sc := bufio.NewScanner(os.Stdin)
	sc.Split(bufio.ScanWords)
	sc.Buffer(make([]byte, 1024), int(1e+9))
	return &Scanner{sc}
}

func (s *Scanner) nextStr() string {
	s.sc.Scan()
	return s.sc.Text()
}

func (s *Scanner) nextInt() int {
	i, e := strconv.Atoi(s.nextStr())
	if e != nil {
		panic(e)
	}
	return i
}

func (s *Scanner) nextFloat() float64 {
	f, e := strconv.ParseFloat(s.nextStr(), 64)
	if e != nil {
		panic(e)
	}
	return f
}

func (s *Scanner) nextRuneSlice() []rune {
	return []rune(s.nextStr())
}

func (s *Scanner) nextIntSlice(n int) []int {
	res := make([]int, n)
	for i := 0; i < n; i++ {
		res[i] = s.nextInt()
	}
	return res
}

func (s *Scanner) nextFloatSlice(n int) []float64 {
	res := make([]float64, n)
	for i := 0; i < n; i++ {
		res[i] = s.nextFloat()
	}
	return res
}

// Arithmetic
func max(nums ...int) int {
	m := nums[0]
	for _, i := range nums {
		if m < i {
			m = i
		}
	}
	return m
}

func min(nums ...int) int {
	m := nums[0]
	for _, i := range nums {
		if m > i {
			m = i
		}
	}
	return m
}

func abs(x int) int {
	if x > 0 {
		return x
	}
	return -x
}

func pow(x, y int) int {
	res := 1
	for i := 0; i < y; i++ {
		res *= x
	}
	return res
}

func ceil(a, b int) int {
	if a%b == 0 {
		return a / b
	} else {
		return a/b + 1
	}
}

// Sort
type RuneSlice []rune

func (a RuneSlice) Len() int           { return len(a) }
func (a RuneSlice) Less(i, j int) bool { return a[i] < a[j] }
func (a RuneSlice) Swap(i, j int)      { a[i], a[j] = a[j], a[i] }

// Main
type Node struct {
	cost int
	done bool
}

type Edge struct {
	to, cost int
}

const INF = 1 << 60

func main() {
	sc := NewScanner()
	wtr := bufio.NewWriter(os.Stdout)
	N := sc.nextInt()
	nodes := make([]Node, N)
	for i := 0; i < N; i++ {
		nodes[i].cost = INF
	}
	E := make([][]Edge, N)
	for i := 0; i < N; i++ {
		id, k := sc.nextInt(), sc.nextInt()
		for j := 0; j < k; j++ {
			to, cost := sc.nextInt(), sc.nextInt()
			E[id] = append(E[id], Edge{to, cost})
		}
	}
	nodes[0].cost = 0
	for {
		cur := 0
		minCost := INF
		for i := 0; i < N; i++ {
			n := nodes[i]
			if !n.done && n.cost < minCost {
				cur = i
				minCost = n.cost
			}
		}
		if minCost == INF {
			break
		}
		nodes[cur].done = true
		for i := 0; i < len(E[cur]); i++ {
			to, cost := E[cur][i].to, E[cur][i].cost+nodes[cur].cost
			if !nodes[to].done && cost < nodes[to].cost {
				nodes[to].cost = cost
			}
		}
	}

	for i := 0; i < N; i++ {
		fmt.Fprintln(wtr, i, nodes[i].cost)
	}
	wtr.Flush()
}

Python: import sys
from operator import add

n = int(sys.stdin.readline().strip())
A = [ [0] for i in range(n)]
for i in range(n):
	temp = map(int ,sys.stdin.readline().strip().split(" "))
	A[i] = temp


weight = [None for i in range(n)]
mitayatu=[False for i in range(n)]

def min(array):
	temp = 100000
	index= 0
	for i in range(n):
		if array[i] is not None and mitayatu[i]==False:
			if temp>=array[i]:
				temp = array[i]
				index = i
	return index

def owari():
	for i in mitayatu:
		if i is False:
			return False
	return True
# zero origin
def prim(nodeid):
	#print(nodeid)
	if owari() == True:
		return
	if mitayatu[nodeid]==True:
		return
	mitayatu[nodeid]=True
	for i in range(n):
		if A[nodeid][i]!=-1:
			if weight[i] is None:
				weight[i]=A[nodeid][i]
			elif weight[i]>A[nodeid][i] and mitayatu[i]==False:
				weight[i]=A[nodeid][i]+weight[nodeid]
	prim(min(weight))

weight[0]=0
prim(0)

#print(weight)
print(reduce(add, weight))

Python: from sys import maxsize

WHITE = 0
GRAY = 1
BLACK = 2


def read_adj():
    n = int(input())
    adj_list = [[] for _ in range(n)]
    for i in range(n):
        u, _, *rest = [int(x) for x in input().split()]
        for i in range(0, len(rest) - 1, 2):
            adj_list[u].append((rest[i], rest[i + 1]))

    return n, adj_list


def shortest_path(n, adj_list):
    color = [WHITE] * n
    dist = [maxsize] * n

    dist[0] = 0
    color[0] = GRAY

    while True:
        minv = maxsize
        u = -1
        for i in range(n):
            if minv > dist[i] and color[i] != BLACK:
                u = i
                minv = dist[i]

        if u == -1:
            break
        color[u] = BLACK

        for v, c in adj_list[u]:
            if dist[u] + c < dist[v]:
                dist[v] = dist[u] + c
                color[v] = GRAY
                
    return dist


def print_dist(dist):
    for u, d in enumerate(dist):
        print(u, d)


def main():
    n, adj_list = read_adj()
    dist = shortest_path(n, adj_list)
    print_dist(dist)


if __name__ == '__main__':
    main()

Python: # input
n = int(input())
A = [[-1] * n for i in range(n)]
for _ in range(n):
    line = list(map(int, input().split()))
    u = line.pop(0)
    k = line.pop(0)
    for i in range(k):
        v = line.pop(0)
        c = line.pop(0)
        A[u][v] = c
    
# 変数定義
inf = 100 * 100000 + 1
M = A.copy()
M = [[a if a > -1 else inf for a in line] for line in M]
d = [inf] * n
V = set([i for i in range(n)]) #nodeの一覧
T = set() #探索済みnodeの一覧

# 探索
start = 0
target = start
d[target] = 0
T.add(target)
while V != T:
    for i in (V - T):
        if d[target] + M[target][i] < d[i]:
            d[i] = d[target] + M[target][i]

    min_wheght = min([d[i] for i in (V - T)])
    min_path = [i for i in (V - T) if d[i] == min_wheght][0]
    target = min_path
    T.add(target)

# 出力
for i in range(n):
    print(f"{i} {d[i]}")

Python: n=int(input())
M=[[-1]*n for _ in[0]*n]
for _ in[0]*n:
 e=list(map(int,input().split()))
 for i in range(e[1]):k=2*-~i;M[e[0]][e[k]]=e[k+1]
d=[0]+[1e6]*~-n
c=[1]*n
while 1:
 m,u=1e6,-1
 for i in range(n):
  if m>d[i]and c[i]:m,u=d[i],i
 if u<0:break
 c[u]=0
 for v in range(n):
  if c[v]and 1+M[u][v]and d[v]>d[u]+M[u][v]:
   d[v]=d[u]+M[u][v]
for i in range(i):print(i,d[i])

Python: # -*- coding: utf-8 -*-

import heapq
q = [] # プライオリティキュー


n = int(input())
V = dict()
d = dict()

for i in range(n):
    data = list(map(int, input().split()))
    V[data[0]] = data[2:]
    d[data[0]] = float('inf')

d[0] = 0
heapq.heappush(q, (0, 0)) #(d[id], id)
S = set()

while len(S) != len(V):
    dist, node_id = heapq.heappop(q)
    S.add(node_id)
    for u, c in zip(V[node_id][0::2], V[node_id][1::2]): #隣接ノード
        if c + d[node_id] < d[u]:
            d[u] = c + d[node_id]
            heapq.heappush(q, (d[u], u))
            #print("Update:", u, d[u])
for i in range(n):
    print(i, d[i])