Problem:
Single Source Shortest Path II For a given weighted graph $G = (V, E)$, find the shortest path from a source to each vertex. For each vertex $u$, print the total weight of edges on the shortest path from vertex $0$ to $u$. Input In the first line, an integer $n$ denoting the number of vertices in $G$ is given. In the following $n$ lines, adjacency lists for each vertex $u$ are respectively given in the following format: $u$ $k$ $v_1$ $c_1$ $v_2$ $c_2$ ... $v_k$ $c_k$ Vertices in $G$ are named with IDs $0, 1, ..., n-1$. $u$ is ID of the target vertex and $k$ denotes its degree. $v_i (i = 1, 2, ... k)$ denote IDs of vertices adjacent to $u$ and $c_i$ denotes the weight of a directed edge connecting $u$ and $v_i$ (from $u$ to $v_i$). Output For each vertex, print its ID and the distance separated by a space character in a line respectively. Print in order of vertex IDs. Constraints  $1 \leq n \leq 10,000$  $0 \leq c_i \leq 100,000$  $|E| < 500,000$  All vertices are reachable from vertex $0$  Sample Input 1 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 Sample Output 1 0 0
1 2
2 2
3 1
4 3 Reference Introduction to Algorithms, Thomas H. Cormen, Charles E. Leiserson, Ronald L. Rivest, and Clifford Stein. The MIT Press.

Solution (Python):


import heapq


class Dijkstra:

    """
    Dijkstra's algorithm: find the shortest path from a vertex
    O(E + log(V))
    verified:
        https://onlinejudge.u-aizu.ac.jp/
    """

    def __init__(self, V, G, INF=float("inf")):

        """
        V: the number of vertexes
        E: adjacency list (all edge in G must be 0 or positive)
        INF: Infinity distance
        """
        self.V = V
        self.G = G
        self.INF = INF
        self.distance, self.prev = list(), list()


    def dijkstra(self, start):

        Q = list()
        self.distance = [self.INF for _ in range(self.V)]
        self.prev = [-1 for _ in range(self.V)]

        self.distance[start] = 0
        heapq.heappush(Q, (0, start))

        while len(Q) > 0:
            dist, from_v = heapq.heappop(Q)
            if self.distance[from_v] < dist:
                continue
            for to_v, nxt_dist in self.G[from_v]:
                if self.distance[from_v] + nxt_dist >= self.distance[to_v]:
                    continue
                self.distance[to_v] = self.distance[from_v] + nxt_dist
                heapq.heappush(Q, (self.distance[to_v], to_v))
                self.prev[to_v] = from_v
        
        return self.distance


    def get_path(self, goal):

        path = [goal]
        while self.prev[goal] != -1:
            path.append(prev[goal])
            goal = self.prev[end]

        return path[::-1]


if __name__ == "__main__":
    
    """
    an example of use
    """

    n = int(input())
    g = [[] for _ in range(n)]
    for _ in range(n):
        v, _, *e = map(int, input().split())
        for u, d in zip(e[::2], e[1::2]):
            g[v].append((u, d))
 

    dist = Dijkstra(n, g).dijkstra(0)
    for i, d in enumerate(dist):
        print(i, d)

Solution (Python):
import heapq

n = int(input())

INF = 2147483647
G = [[] for i in range(n)]
check, dist = [0 for i in range(n)], [INF for i in range(n)]


def dijkstra(s):
    dist[s], pq = 0, []
    heapq.heappush(pq, (0, s))

    while len(pq) != 0:
        u = heapq.heappop(pq)
        check[u[1]] = 2

        if dist[u[1]] < u[0]:
            continue

        for v in G[u[1]]:
            if check[v[0]] != 2:
                if dist[u[1]] + v[1] < dist[v[0]]:
                    dist[v[0]], check[v[0]] = dist[u[1]] + v[1], 1
                    heapq.heappush(pq, (dist[v[0]], v[0]))


def main():
    for i in range(n):
        data = list(map(int, input().split()))
        for j in range(data[1]):
            G[data[0]].append((data[2*(j+1)], data[2*(j+1)+1]))

    dijkstra(0)

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


if __name__ == '__main__':
    main()

Solution (Python):
import heapq

class Dijkstra:
    """
        Dijkstra's algorithm: find the shortest paths from a vertex
        complexity:
            O(E + logV)
    """
    def __init__(self, V, E, start, INF=10**9):
        """
        :param V: the number of vertices
        :param E: adjacency list (all edge in E must be non negative)
        :param start: start vertex
        :param INF: Infinity distance
        """
        self.V = V
        self.E = E
        self.dijkstra(start, INF)

    def dijkstra(self, start, INF):
        que = list()
        self.distance = [INF] * self.V
        self.prev = [-1] * self.V
        self.distance[start] = 0
        heapq.heappush(que, (0, start))
        while len(que) > 0:
            dist, fr = heapq.heappop(que)
            if self.distance[fr] < dist:
                continue
            for to, cost in self.E[fr]:
                if self.distance[fr] + cost < self.distance[to]:
                    self.distance[to] = self.distance[fr] + cost
                    heapq.heappush(que, (self.distance[to], to))
                    self.prev[to] = fr

    def get_path(self, end):
        path = [end]
        while self.prev[end] != -1:
            end = self.prev[end]
            path.append(end)
            return path[::-1]


V = int(input())
edges = [[] for _ in range(V)]
for _ in range(V):
    u, _, *e = map(int, input().split())
    for t, d in zip(e[::2], e[1::2]):
        edges[u].append((t, d))

djk = Dijkstra(V, edges, 0)
for i, d in enumerate(djk.distance):
    print(i, d)

Solution (Python):
import sys
    
def shortest_path(GRAPH, distance):
    
    nodes0 = range(len(distance))
    nodes1 = set()
    p1 = 0
    distance[p1] = 0
    while True:
        dp1 = distance[p1]
        gp1 = GRAPH[p1]
        status[p1]=2
        for p2 in gp1.keys():
            tmp = gp1[p2] + dp1
            if status[p2]<=1 and tmp < distance[p2]:
                distance[p2] = tmp
                status[p2] = 1
                nodes1.add(p2)

        p1 = -1
        mini = 1000000
            
        for p2 in nodes1:
            if distance[p2]<mini:
                p1 = p2
                mini = distance[p2]
        if mini == 1000000:
            break
        nodes1.remove(p1)
    return

def resultout(distance):
    for i in xrange(len(distance)):
        print "%d %d" %(i, distance[i])
    return

n = int(raw_input())
x = [{} for i in xrange(n)]
status = [0 for i in xrange(n)]
distance = [1000000 for i in xrange(n)]

for i in xrange(n):
    seq = map(int, raw_input().split())
    tmp={}
    for j in xrange(2, len(seq), 2):
        j2, weight = seq[j:j+2]
        tmp[j2] = weight
    x[seq[0]] = tmp
    status[i] = 0

shortest_path(x, distance)
resultout(distance)

Solution (Python):
import sys
    
def shortest_path(GRAPH, distance):
    
    nodes = set()
    p1 = 0
    distance[p1] = 0

    while True:
        dp1 = distance[p1]
        gp1 = GRAPH[p1]
        status[p1]=1
        for p2 in gp1.keys():
            tmp = gp1[p2] + dp1
            if status[p2]==0 and tmp < distance[p2]:
                distance[p2] = tmp
                nodes.add(p2)

        p1 = -1
        mini = 1000000
            
        for p2 in nodes:
            if distance[p2]<mini:
                p1 = p2
                mini = distance[p2]
        if mini == 1000000:
            break
        nodes.remove(p1)
    return

def resultout(distance):
    for i in xrange(len(distance)):
        print "%d %d" %(i, distance[i])
    return

n = int(raw_input())
x = [{} for i in xrange(n)]
status = [0 for i in xrange(n)]
distance = [1000000 for i in xrange(n)]

for i in xrange(n):
    seq = map(int, raw_input().split())
    tmp={}
    for j in xrange(2, len(seq), 2):
        j2, weight = seq[j:j+2]
        tmp[j2] = weight
    x[seq[0]] = tmp
    status[i] = 0

shortest_path(x, distance)
resultout(distance)

Solution (Python):

from __future__ import division, print_function
from sys import stdin, maxint


def main():
    num = int(stdin.readline())

    edges = []
    for _ in xrange(num):
        ns = [int(s) for s in stdin.readline().split()]
        for i in xrange(ns[1]):
            edges.append((ns[0], ns[2*i+2], ns[2*i+3]))

    dis = [maxint] * num
    dis[0] = 0

    while 1:
        update = False
        for from_, to, cost in edges:
            if dis[from_] < maxint and dis[to] > cost + dis[from_]:
                dis[to] = cost + dis[from_]
                update = True

        if not update:
            break

    for i, d in enumerate(dis):
        print(i, d)


main()

Solution (Python):

from __future__ import division, print_function
from sys import stdin, maxsize


def main():
    num = int(stdin.readline())

    edges = []
    for _ in range(num):
        ns = [int(s) for s in stdin.readline().split()]
        for i in range(ns[1]):
            edges.append((ns[0], ns[2*i+2], ns[2*i+3]))

    dis = [maxsize] * num
    dis[0] = 0

    while 1:
        update = False
        for from_, to, cost in edges:
            if dis[from_] < maxsize and dis[to] > cost + dis[from_]:
                dis[to] = cost + dis[from_]
                update = True

        if not update:
            break

    for i, d in enumerate(dis):
        print(i, d)


main()

Solution (Python):
from heapq import heappop, heappush
from collections import defaultdict


class Dijkstra:
    """Graph input:
    {
    node:{node:cost,node:cost...},
    node:{node:cost,node:cost...},
    ...
    }
    """

    def __init__(self, graph: dict, N: int):
        self.graph = graph
        self.costs = [float("inf")] * N

    def calculate(self, start):
        queue = list()

        
        self.costs[start] = 0
        heappush(queue, (0, start))  

        while queue:
            
            cost_from_start, min_node = heappop(queue)

            
            for link, cost in self.graph[min_node].items():
                if cost_from_start + cost < self.costs[link]:
                    self.costs[link] = cost_from_start + cost
                    heappush(queue, (self.costs[link], link))

        return self.costs


n = int(input())
graph = defaultdict(dict)

for _ in range(n):
    data = [int(i) for i in input().split()]
    u = data[0]
    count = data[1]
    for j in range(1, count + 1):
        v = data[2 * j]
        w = data[2 * j + 1]
        graph[u][v] = w

dijkstra = Dijkstra(graph, n)
costs = dijkstra.calculate(0)

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

Solution (Python):
import sys, os, math, bisect, itertools, collections, heapq, queue, copy, array





sys.setrecursionlimit(10000000)

ii = lambda: int(sys.stdin.buffer.readline().rstrip())
il = lambda: list(map(int, sys.stdin.buffer.readline().split()))
fl = lambda: list(map(float, sys.stdin.buffer.readline().split()))
iln = lambda n: [int(sys.stdin.buffer.readline().rstrip()) for _ in range(n)]

iss = lambda: sys.stdin.buffer.readline().decode().rstrip()
sl = lambda: list(map(str, sys.stdin.buffer.readline().decode().split()))
isn = lambda n: [sys.stdin.buffer.readline().decode().rstrip() for _ in range(n)]

lcm = lambda x, y: (x * y) // math.gcd(x, y)

MOD = 10 ** 9 + 7
INF = float('inf')


def main():
    if os.getenv("LOCAL"):
        sys.stdin = open("input.txt", "r")

    N = ii()

    
    graph = [[] for _ in range(N)]
    for _ in range(N):
        v1, k, *vertices = il()
        for idx in range(0, k * 2, 2):
            v2, c = vertices[idx:idx + 2]
            graph[v1].append((c, v2))

    
    dist = [INF] * N    
    dist[0] = 0         
    visited = [0] * N   
    heap = [(0, 0)]     
    heapq.heapify(heap) 
    while heap:
        
        min_cost, u = heapq.heappop(heap)

        
        if dist[u] < min_cost: continue
        visited[u] = 1  

        
        for cost, v in graph[u]:
            if visited[v] != 1:
                if dist[u] + cost < dist[v]:
                    
                    
                    dist[v] = dist[u] + cost
                    heapq.heappush(heap, (dist[v], v))
    
    for n in range(N):
        print(n, dist[n])


if __name__ == '__main__':
    main()

Solution (Python):
from sys import stdin
input = stdin.readline
import heapq

infty = 2**21

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

    d[0] = 0
    PQ = [(0, 0)]
    heapq.heapify(PQ)
    color[0] = 1

    while PQ:
        f = heapq.heappop(PQ)
        u = f[1]
        color[u] = 2

        
        if d[u] < f[0]:
            continue

        for adj_u in adj[u]:
            v = adj_u[0]
            if color[v] == 2:
                continue
            if d[v] > d[u] + adj_u[1]:
                d[v] = d[u] + adj_u[1]
                heapq.heappush(PQ, (d[v], v))
                color[v] = 1


    for i in range(n):
        print(str(i) + ' ' + str(-1 if d[i] == infty else d[i]))


n = int(input())

adj = [0]*n

for _ in range(n):
    u, k, *vc = map(int, input().split())
    vx_tuple = [0] * k
    for i, (v, c) in enumerate(zip(vc[::2], vc[1::2])):
        
        vx_tuple[i] = (v, c)
    adj[u] = vx_tuple


dijkstra(n)

Solution (Python):
import queue

def dijkstra(s):
    color = ["white"]*n
    d = [float('inf')]*n
    d[s] = 0
    
    pq = queue.PriorityQueue()
    
    pq.put((0,s))
    
    while not pq.empty():
        u = pq.get()
        color[u[1]] = "black"
        
        if d[u[1]] < u[0]:
            continue
            
        for v,w in zip(Adj[u[1]][2::2],Adj[u[1]][3::2]):
            if color[v] != "black":
                if d[u[1]] + w < d[v]:
                    d[v] = d[u[1]]+w
                    color[v] = "gray"
                    pq.put((d[v],v))
                    
    return d

n = int(input())
Adj = [list(map(int,input().split())) for _ in range(n)]
ans = dijkstra(0)

for i in range(n):
    print('{} {}'.format(i,ans[i]))

Solution (Python):
import heapq
n=int(input())
p=[-1 for i in range(n)]
inf=100000000
d=[inf for i in range(n)]
M=[[] for i in range(n)]
color=["white" for i in range(n)]
Q=[]
heapq.heapify(Q)

for i in range(n):
    tmp=list(map(int,input().split()))
    root=tmp[0]
    k=tmp[1]
    for j in range(k):
        M[root].append((tmp[2*(j+1)+1],tmp[2*(j+1)]))

def dijkstra(s):
    d[s]=0
    heapq.heappush(Q,(d[s],s))
    color[s]="gray"
    while Q:
        f=heapq.heappop(Q)

        u=f[1]
        color[u]="Black"
        if f[0]>d[u]:
            continue
        for i in range(len(M[u])):
            if color[M[u][i][1]]!="Black":
                v=M[u][i][1]
                if d[v]>d[u]+M[u][i][0]:
                    d[v]=d[u]+M[u][i][0]
                    color[M[u][i][1]]="gray"
                    heapq.heappush(Q,(d[M[u][i][1]],M[u][i][1]))
                    
dijkstra(0)

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

Solution (Python):
import heapq
from collections import deque
from enum import Enum
import sys
import math
from _heapq import heappush, heappop
import copy
from test.support import _MemoryWatchdog

BIG_NUM = 2000000000
HUGE_NUM = 99999999999999999
MOD = 1000000007
EPS = 0.000000001
sys.setrecursionlimit(100000)


class Edge:
    def __init__(self,arg_to,arg_dist):
        self.to = arg_to
        self.dist = arg_dist

class Info:
    def __init__(self,arg_node_id,arg_sum_dist):
        self.node_id = arg_node_id
        self.sum_dist = arg_sum_dist

    def __lt__(self,another):
        return self.sum_dist < another.sum_dist


V = int(input())
G = [[] for _ in range(V)] 
min_dist = [BIG_NUM]*V

for _ in range(V):
    node_id,num_adj,*tmp_array = list(map(int,input().split()))
    for i in range(0,len(tmp_array),2):
        G[node_id].append(Edge(tmp_array[i],tmp_array[i+1]))

min_dist[0] = 0
Q = []
heappush(Q, Info(0,0))

while len(Q) > 0:
    info = heappop(Q)
    if info.sum_dist > min_dist[info.node_id]:continue
    for e in G[info.node_id]:
        if min_dist[e.to] > info.sum_dist+e.dist:
            min_dist[e.to] = info.sum_dist+e.dist
            heappush(Q, Info(e.to,min_dist[e.to]))

for i in range(V):
    print("%d %d"%(i,min_dist[i]))

Solution (Python):
from heapq import *
n = int(input())
INF = float("inf")
adj = [[] for _ in range(10**4+4)]
for _ in range(n):
    a,*b = map(int,input().split())
    if b[0] != 0:
        c = b[1:]
        for i in range(len(c)//2):
            k,w = c[2*i],c[2*i+1]
            adj[a].append((k,w))
H = []
heapify(H)
searched = [0]*n
d = [INF]*n
d[0] = 0
heappush(H, (0,0))
while H:
    f = heappop(H)
    u = f[-1]
    searched[u] = 1
    if d[u] < f[0]:
        continue
    for j in range(len(adj[u])):
        v = adj[u][j][0]
        if searched[v]:
            continue
        if d[v] > d[u]+adj[u][j][-1]:
            d[v] = d[u]+adj[u][j][-1]
            heappush(H,(d[v],v))
for i in range(n):
    ans = -1 if d[i] == INF else d[i]
    print(i,ans)

Solution (Python):
import heapq

N = int(input())
A = [[]for i in range(N)]

for i in range(N):
    u, k, *nums = list(map(int,input().split()))
    for j in range(k):
        t = nums[j*2]
        c = nums[j*2+1]
        A[u].append([t, c])

memo = [1E18] * N
memo[0] = 0
qu = []
heapq.heappush(qu, (0,0))
while len(qu) != 0:
    atop = heapq.heappop(qu)
    for ne in A[atop[1]]:
        x = ne[0]
        next_cost = atop[0] + ne[1]
        if(memo[x] > next_cost):
            memo[x] = next_cost
            heapq.heappush(qu, (next_cost, x))
for i in range(N):
    print(i, memo[i])

Solution (Python):
import sys, collections, heapq
input = lambda: sys.stdin.readline().rstrip() 
sys.setrecursionlimit(10**7)
INF = 10**10
def I(): return int(input())
def F(): return float(input())
def SS(): return input()
def LI(): return [int(x) for x in input().split()]
def LI_(): return [int(x)-1 for x in input().split()]
def LF(): return [float(x) for x in input().split()]
def LSS(): return input().split()

def dijkstra(G, s):
    que = []
    d = [INF]*len(G)
    d[s] = 0
    heapq.heappush(que, (d[s], s))

    while que:
        p = heapq.heappop(que)
        v = p[1]
        if d[v] < p[0]: continue
        for e in G[v]:
            if d[e[0]] > d[v] + e[1]:
                d[e[0]] = d[v] + e[1]
                heapq.heappush(que, (d[e[0]], e[0]))
    return d

def resolve():
    n = I()
    G = [[] for _ in range(n)]
    for i in range(n):
        ukvc = LI()
        u = ukvc[0]
        k = ukvc[1]
        for j in range(k):
            v = ukvc[2*j+2]
            c = ukvc[2*j+3]
            G[u].append((v, c))

    ans = dijkstra(G, 0)
    for i, e in enumerate(ans):
        print(i, e)

if __name__ == '__main__':
    resolve()

Solution (Python):
from heapq import heappush, heappop
import sys
INFTY=sys.maxsize

def readinput():
    n=int(input())
    nList=[]
    for _ in range(n):
        nList.append([])
    for _ in range(n):
        l=list(map(int,input().split()))
        i=l[0]
        k=l[1]
        for j in range(k):
            v=l[2+j*2]
            c=l[2+j*2+1]
            nList[i].append([v,c])
    return n,nList

def dijkstra(s,n,nList):
    WHITE=0
    GRAY=1
    BLACK=2
    color=[WHITE]*n
    d=[INFTY]*n

    HQ=[]

    d[s]=0
    heappush(HQ,(d[s],s))

    while(len(HQ)>0):
        du,u=heappop(HQ)
        color[u]=BLACK

        if d[u]<du:
            continue

        for (v,vw) in nList[u]:
            if color[v]!=BLACK:
                if d[u] + vw < d[v]:
                    d[v] = d[u] + vw
                    color[v]=GRAY
                    heappush(HQ, (d[v], v))
    return d


def main(n,nList):
    d=dijkstra(0,n,nList)    
    for i in range(n):
        print('{} {}'.format(i,d[i]))

    return

if __name__=='__main__':
    n,nList=readinput()
    main(n,nList)

Solution (Python):









import os
import sys
from collections import deque




def main():
    n = int(input())
    graph = [[] for _ in range(n)]
    for _ in range(n):
        line = list(map(int,input().split()))
        u,k = line[0],line[1]
        path = line[2:]
        for i in range(0,2*k,2):
            graph[u].append([path[i+1],path[i]])
    

    s=0
    distance=[-1]*n
    Q = deque([s])
    distance[0]=0
    

    while Q:
        u = Q.popleft()
        for dis,v in graph[u]:
            if distance[v]==-1:
                distance[v]=distance[u]+dis
                Q.append(v)

            if distance[v]>distance[u]+dis:
                distance[v]=distance[u]+dis
                Q.append(v)
            


    for i,dis in enumerate(distance):
        print(i,dis)


if __name__ == "__main__":
    main()

Solution (Python):

import sys
import heapq
input=sys.stdin.readline

def dijkstra(G,start,n):
    INF=2<<28
    dist=[INF]*n;dist[start]=0
    used=[False]*n;used[start]=True
    q=[]

    for v in G[start]:
        heapq.heappush(q,v)
    
    while len(q)>0:
        now1,now2=heapq.heappop(q)
        
        if used[now2]:
            continue
        v=now2
        dist[v]=now1
        used[v]=True

        for e1,e2 in G[v]:
            if not used[e2]:
                heapq.heappush(q,(e1+dist[v],e2))

    return dist

def main():
    N=int(input().rstrip())
    g=[[] for _ in range(N)]
    for _ in range(N):
        u,k,*c=map(int,input().split())
        for j in range(0,k*2,2):
            g[u].append((c[j+1],c[j]))

    ans=dijkstra(g,0,N)
    for i,x in enumerate(ans):
        print(i,x)

if __name__=="__main__":
    main()

Solution (Python):
import heapq
N=int(input())
rinsetu=[[] for j in range(N)]
d=[1000000]*(N)

color=["white"]*N
for i in range(N):
    a=list(map(int,input().split()))
    for j in range(a[1]):
        j1=j*2+2
        j2=j*2+3
        rinsetu[i].append([a[j1],a[j2]])
def hunterhunter():
    d[0]=0
    heap=[]
    heapq.heapify(heap)
    heapq.heappush(heap,[0,0])
    while(heap):
        mincost=heapq.heappop(heap)
        u=mincost[1]
        color[u]="black"
        for  i in rinsetu[u]:
            if color[i[0]]=="white":
                if i[1]+d[u]<d[i[0]]:
                    d[i[0]]=i[1]+d[u]
                    heapq.heappush(heap,[d[i[0]],i[0]])
hunterhunter()
for i,cost in enumerate(d):
    print(i,cost)

Solution (Python):
from heapq import heapify,heappop,heappush

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

    def dijkstra(self,st):
        INF = 10**9+1
        D = [INF for i in range(len(self.V))]
        
        D[st] = 0
        Q = [[0,st]]
        Used = set()
        
        
        while len(Used) < len(self.V):
            p = heappop(Q)
            p_dist,p_ind = p[0],p[1]
            for e in self.E[p_ind]:
                to,cost = e[0],e[1]
                if to not in Used:
                    if D[to] > D[p_ind] + cost:
                        D[to] = D[p_ind] + cost
                        heappush(Q,[D[to],to])
            Used.add(p_ind)

        return D

def main():
    n = int(input())
    V = [i for i in range(n)]
    E = [set() for _ in range(n)]
    
    
    for i in range(n):
        I = list(map(int,input().split()))
        for j in range(2,len(I)):
            if j % 2 == 0:
                E[i].add((I[j],I[j+1]))

    G = Graph(V,E)

    ans = G.dijkstra(0)
    for i in range(n):
        print(i,ans[i])

if __name__ == "__main__":
    main()

Solution (Python):
import sys
readline = sys.stdin.readline
from heapq import heapify, heappush, heappop
INF = float("inf")
def MAIN():
    n = int(input())
    adj = [[]] * n
    for _ in range(0, n):
        U = list(map(int, input().split()))
        adj[U[0]] = zip(U[2::2], U[3::2])
    def dijkstra():
        d = [0] + [INF] * (n - 1)
        hq = [(0, 0)]
        while hq:
            u = heappop(hq)[1]
            for v, c in adj[u]:
                alt = d[u] + c
                if d[v] > alt:
                    d[v] = alt
                    heappush(hq, (alt, v))
        print("\n".join(f"{i} {c}" for i, c in enumerate(d)))
    dijkstra()
MAIN()

Solution (Python):
import heapq

n = int(input())
C = [[] for _ in range(n)]
for _ in range(n):
    tmp = list(map(int,input().split()))
    for i in range(1,tmp[1]+1):
        C[tmp[0]].append(tuple(tmp[2*i:2*i+2]))

q = []

def heap_dijkstra(start = 0):
    visited = [False]*n
    INF = 10000000000
    d = [INF]*n

    d[start] = 0
    visited[start] = True
    add_node = start

    for i in range(n-1):
        for adj_weight in C[add_node]:
            if visited[adj_weight[0]] == False:
                heapq.heappush(q,(d[add_node]+adj_weight[1],adj_weight[0]))

        while 1:
            tmp = heapq.heappop(q)
            if visited[tmp[1]] == False:
                min_weight = tmp[0]
                min_node = tmp[1]
                break
        
        add_node = min_node
        visited[min_node] = True
        d[min_node] = min_weight
    
    return d

D = heap_dijkstra()

for i in range(n):
    print("{} {}".format(i,D[i]))

Solution (Python):
from heapq import heapify, heappop, heappush, heappushpop


class PriorityQueue:
    def __init__(self, heap):
        '''
        heap ... list
        '''
        self.heap = heap
        heapify(self.heap)

    def push(self, item):
        heappush(self.heap, item)

    def pop(self):
        return heappop(self.heap)

    def pushpop(self, item):
        return heappushpop(self.heap, item)

    def __call__(self):
        return self.heap

    def __len__(self):
        return len(self.heap)


def dijkstra(graph, s, N):
    '''
    graph...隣接リスト形式 リスト内要素は(ノード, エッジ長)
    s...始点ノード
    N...頂点数

    return
    ----------
    D ... 各点までの最短距離
    P ... 最短経路木における親
    '''
    pq = PriorityQueue([])
    P = [None] * N
    D = [float('inf')] * N
    D[s] = 0
    pq.push((D[s], s))  
    while pq:
        d, v = pq.pop()
        if D[v] < d:  
            continue  
        for to, cost in graph[v]:
            if D[to] > D[v] + cost:  
                D[to] = D[v] + cost
                pq.push((D[to], to))
                P[to] = v
    return D, P


N = int(input())
adj = [[] for _ in range(N)]  
'''
例
[
(0について) [(1,1235), (4,65)]
(1について) [(20,6000)]
...
]
'''
for _ in range(N):
    tmp = list(map(int, input().split()))
    if tmp[1] != 0:
        node = tmp[0]
        for i in range(2, 2 + tmp[1] * 2, 2):
            adj[node].append((tmp[i], tmp[i + 1]))

D, P = dijkstra(adj, 0,N)

for i in range(N):
    print(i, D[i])

Solution (Python):
import sys,collections
N = int(sys.stdin.readline())
G = tuple(tuple(map(int,sys.stdin.readline().rstrip().split()))[2:] for _ in range(N)) 


INF = float("inf")
ALL = set(range(N))
mst = set()
distances = [INF]*N 
distances[0] = 0
parents = [INF]*N
parents[0] = 0

import heapq

dv = []
def add(u):
  mst.add(u)
  if not ALL-mst: return
  for j in range(0,len(G[u]),2):
    v = G[u][j]
    w = G[u][j+1]
    if not v in mst and w + distances[u] < distances[v]: 
      distances[v] = distances[u]+w
      parents[v] = u
      heapq.heappush(dv, (distances[v],v))
  
  d,v = heapq.heappop(dv)
  while v in mst:
    d,v = heapq.heappop(dv)
  return v

n = add(0)
distances[0] = 0
parents[0]=0
while len(mst) < len(G):
  n = add(n)

for i in range(N):
  print(i,distances[i])

Solution (Python):
def E_dijkstra(V,AL,S):
    from heapq import heappush,heappop
    INF=float('inf')
    ans=[INF]*V
    ans[S]=0
    used=[0]*V 
    used[S]=1
    que=[]
    for i in range(V):
        heappush(que,(ans[i],i))
    while que:
        x,u=heappop(que)
        used[u]=1
        for v,w in AL[u]:
            if not used[v] and ans[v]>x+w:
                ans[v]=x+w
                heappush(que,(ans[v],v))
    return ans












import sys
input = sys.stdin.readline

N=int(input())
AL=[[] for _ in range(N)]
for _ in range(N):
    for i,x in enumerate(input().split()):
        x=int(x)
        if i==0:
            j=x
        elif i==1:
            pass
        else:
            if i%2==0:
                tmp=[x]
            else:
                tmp.append(x)
                AL[j].append(tmp)
for ans in enumerate(E_dijkstra(N,AL,0)):
    print(*ans)

Solution (Python):
import heapq

n = int(input())
maxim = 100010
adj = [[] for _ in range(n)]

for _ in range(n):
    u, k, *v = map(int, input().split())
    if k == 0:
        adj[u].append((0,0))
    for i in range(k):
        adj[u].append((v[i*2+1], v[i*2]))

def dijkstra():
    global adj
    PQ = []
    heapq.heapify(PQ)
    color = ['W']*n
    d = [maxim]*n
    d[0] = 0
    heapq.heappush(PQ, (0, 0))
    color[0] = 'G'

    while PQ:
        f = heapq.heappop(PQ)
        u = f[1]
        color[u] = 'B'
        if d[u] < f[0]*-1:
            continue
        for j in range(len(adj[u])):
            v = adj[u][j][1]
            if color[v] == 'B':
                continue
            if d[v] > d[u]+adj[u][j][0]:
                d[v] = d[u]+adj[u][j][0]
                heapq.heappush(PQ, (d[v], v))
                color[v] = 'G'
    return d

D = dijkstra()
for i, x in enumerate(D):
    print(i, x)

Solution (Python):
from heapq import heapify, heappop, heappush, heappushpop
INF = 10**6 + 1

class PriorityQueue:
    def __init__(self, heap):
        self.heap = heap
        heapify(self.heap)

    def push(self, item):
        heappush(self.heap, item)

    def pop(self):
        return heappop(self.heap)

    def pushpop(self, item):
        return heappushpop(self.heap, item)

    def __call__(self):
        return self.heap

    def __len__(self):
        return len(self.heap)


def dijkstra(adj: list, s: int):
    Color = [0] * N
    D = [INF] * N
    P = [None] * N

    D[s] = 0
    P[s] = None
    PQ = PriorityQueue([(0, s)])

    while PQ:
        min_cost, u = PQ.pop()

        Color[u] = 2

        if D[u] < min_cost:
            continue

        for idx_adj_u, w_adj_u in adj[u]:
            if Color[idx_adj_u] != 2:
                if D[u] + w_adj_u < D[idx_adj_u]:
                    D[idx_adj_u] = D[u] + w_adj_u
                    P[idx_adj_u] = u
                    PQ.push((D[idx_adj_u], idx_adj_u))
                    Color[idx_adj_u] = 1
    return D, P

N = int(input())
adj = [[] for _ in range(N)]
for _ in range(N):
    tmp = list(map(int, input().split()))
    if tmp[1] != 0:
        node = tmp[0]
        for i in range(2, 2 + tmp[1] * 2, 2):
            adj[node].append((tmp[i], tmp[i + 1]))

D, P = dijkstra(adj, 0)

for i in range(N):
    print(i, D[i])

Solution (Python):
n=int(input())
inf=10**15;d=[inf]*n;d[0]=0
node=[[]for _ in range(n)]
for i in range(n):
	x=list(map(int,input().split()))
	for j in range(x[1]):
		node[i].append((x[j*2+2],x[j*2+3]))
from heapq import heappush,heappop
pq=[]
visited=[False]*n
heappush(pq,(0,0))
while pq:
	u=heappop(pq)
	u_dis=u[0];u_num=u[1]
	visited[u_num]=True
	for x in node[u_num]:
		x_dis=x[1];x_num=x[0]
		if visited[x_num]==False:
			if d[u_num]+x_dis<d[x_num]:
				d[x_num]=d[u_num]+x_dis
				heappush(pq,(d[x_num],x_num))
				
for i in range(n):
	print(i,d[i])

Solution (Python):
import sys
input = sys.stdin.buffer.readline

import heapq



def dijkstra(s, n, edge): 
    INF = 10**20
    d = [INF]*n 
    used = [True]*n 
    d[s] = 0 
    used[s] = False 
    edge_list = []
    for a, b in edge[s]:
        heapq.heappush(edge_list, a*(10**6)+b) 
    while len(edge_list):
        min_edge = heapq.heappop(edge_list) 
        if not used[min_edge%(10**6)]: 
            continue
        v = min_edge%(10**6) 
        d[v] = min_edge // (10**6) 
        used[v] = False
        for e in edge[v]:
            if used[e[1]]: 
                heapq.heappush(edge_list, (e[0]+d[v])*(10**6) + e[1])
        
    return d


n = int(input())

edge = [[] for _ in range(n)] 
for _ in range(n):
    x, y, *li = list(map(int, input().split()))
    for i in range(y):
        edge[x].append((li[2*i+1], li[2*i]))
        

d = dijkstra(0, n, edge)

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