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

from heapq import heappush, heappop



N = int(eval(input()))

INF = float("inf")

adj = []

for _ in range(N):

    inp = tuple(map(int, input().split()))

    adj.append(tuple(zip(inp[2::2], inp[3::2])))



checked = [False for _ in range(N)]

d = [float("inf") for _ in range(N)]

d[0] = 0



heap = [[0, 0]] # cost, vec



while heap:

    c, u = heappop(heap)

    if d[u] < c or checked[u]:

        continue

    for nu, nc in adj[u]:

        new_d = d[u] + nc

        if new_d < d[nu]:

            d[nu] = new_d

            heappush(heap, [d[nu], nu])

    checked[u] = True



for n in range(N):

    print(("{} {}".format(n, d[n])))
# -*- coding: utf-8 -*-

from heapq import heappop, heappush

def inpl(): return list(map(int, input().split()))

INF = float("inf")

N = int(eval(input()))

G = []

for _ in range(N):

    I = inpl()

    G.append(list(zip(*[I[3::2], I[2::2]])))



def dijkstra(G):

    C = [INF]*(N)

    C[0] = 0

    visited = [False] * (N)

    Q = [[0, 0]]



    while Q:

        c, u = heappop(Q)

        if C[u] < c:

            continue

        visited[u] = True

        for d, v in G[u]:

            if visited[v]:

                continue

            e = c + d

            if e < C[v]:

                C[v] = e

                heappush(Q, [e, v])

    return C



for i, c in enumerate(dijkstra(G)):

    print((i, c))

# -*- coding: utf-8 -*-
from heapq import heappush, heappop

N = int(eval(input()))
INF = float("inf")
adj = []
for _ in range(N):
    inp = tuple(map(int, input().split()))
    adj.append(tuple(zip(inp[2::2], inp[3::2])))
checked = [False for _ in range(N)]
d = [float("inf") for _ in range(N)]
d[0] = 0
heap = [[0, 0]]  # cost, vec
while heap:
    c, u = heappop(heap)
    if d[u] < c or checked[u]:
        continue
    for nu, nc in adj[u]:
        new_d = d[u] + nc
        if new_d < d[nu]:
            d[nu] = new_d
            heappush(heap, [d[nu], nu])
    checked[u] = True
for n in range(N):
    print(("{} {}".format(n, d[n])))

# -*- coding: utf-8 -*-
from heapq import heappop, heappush


def inpl():
    return list(map(int, input().split()))


INF = float("inf")
N = int(eval(input()))
G = []
for _ in range(N):
    I = inpl()
    G.append(list(zip(*[I[3::2], I[2::2]])))


def dijkstra(G):
    C = [INF] * (N)
    C[0] = 0
    visited = [False] * (N)
    Q = [[0, 0]]
    while Q:
        c, u = heappop(Q)
        if C[u] < c:
            continue
        visited[u] = True
        for d, v in G[u]:
            if visited[v]:
                continue
            e = c + d
            if e < C[v]:
                C[v] = e
                heappush(Q, [e, v])
    return C


for i, c in enumerate(dijkstra(G)):
    print((i, c))

-from heapq import heappush, heappop +from heapq import heappop, heappush + +def inpl(): +    return list(map(int, input().split())) + + +INF = float("inf") -INF = float("inf") -adj = [] +G = [] -    inp = tuple(map(int, input().split())) -    adj.append(tuple(zip(inp[2::2], inp[3::2]))) -checked = [False for _ in range(N)] -d = [float("inf") for _ in range(N)] -d[0] = 0 -heap = [[0, 0]]  # cost, vec -while heap: -    c, u = heappop(heap) -    if d[u] < c or checked[u]: -        continue -    for nu, nc in adj[u]: -        new_d = d[u] + nc -        if new_d < d[nu]: -            d[nu] = new_d -            heappush(heap, [d[nu], nu]) -    checked[u] = True -for n in range(N): -    print(("{} {}".format(n, d[n]))) +    I = inpl() +    G.append(list(zip(*[I[3::2], I[2::2]]))) + + +def dijkstra(G): +    C = [INF] * (N) +    C[0] = 0 +    visited = [False] * (N) +    Q = [[0, 0]] +    while Q: +        c, u = heappop(Q) +        if C[u] < c: +            continue +        visited[u] = True +        for d, v in G[u]: +            if visited[v]: +                continue +            e = c + d +            if e < C[v]: +                C[v] = e +                heappush(Q, [e, v]) +    return C + + +for i, c in enumerate(dijkstra(G)): +    print((i, c))