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

C++: #include<bits/stdc++.h>
#define INF 10000000
#define NIL -1
#define BLACK 2
#define WHITE 0
#define GRAY 1
#define MAX 100
using namespace std;

int color[MAX]={},d[MAX]={},pi[MAX]={},n;

void initializeSingleSource(int w[MAX][MAX]){
    for(int v=0;v<n;v++){
        d[v]=INF;
        pi[v]=NIL;
    }
    d[0]=0;
}

void relax(int u,int v,int w[MAX][MAX]){
    if(d[v]>d[u]+w[u][v]){
        d[v]=d[u]+w[u][v];
        pi[v]=u;
    }
}

void dijkstra(int w[MAX][MAX]){
    int mincost,i,v,u;
    initializeSingleSource(w);
    while(1){
        mincost=INF;
        u=NIL;
        for(i=0;i<n;i++){
            if(color[i]!=BLACK&&d[i]<mincost){
                mincost=d[i];
                u=i;
            }
        }
        if(u==NIL)break;
        color[u]=BLACK;
        for(v=0;v<n;v++){
            if(color[v]!=BLACK&&d[u]+w[u][v]<d[v]){
                pi[v]=u;
                d[v]=d[u]+w[u][v];
                color[v]=GRAY;
            }
        }
    }
}

void prim(int w[MAX][MAX]){
    int u,i,v,mincost,j;
    for(u=0;u<n;u++){
        d[u]=INF;
        pi[u]=NIL;
        color[u]=WHITE;
    }
    d[0]=0;
    while(1){
        mincost = INF;
        u=-1;
        for(i=0;i<n;i++){
            if(color[i]!=BLACK&&d[i]<mincost){
                mincost=d[i];
                u=i;
            }
        }
        if(u==-1)break;
        color[u]=BLACK;
        for(v=0;v<n;v++){
            if(color[v]!=BLACK&&w[u][v]!=INF){
                if(d[v]>w[u][v]){
                    pi[v]=u;
                    d[v]=w[u][v];
                    color[v]=GRAY;
                }
            }
        }
    }
    int sum=0;
    for(i=0;i<n;i++){
        if(pi[i]!=NIL)sum+=w[i][pi[i]];
    }

    for(i=0;i<n;i++){
        for(j=0;j<n;j++){
            cout<<w[i][j]<<" ";
        }
        cout<<endl;
    }

    cout<<endl;

    for(i=0;i<n;i++){
        cout<<pi[i]<<" ";
    }
    cout<<endl;
}

int main(){
    int w[MAX][MAX],i,j,id,k,weight,gow,ans;
    cin>>n;
    for(i=0;i<MAX;i++){
        for(j=0;j<MAX;j++){
            w[i][j]=INF;
        }
    }
    for(i=0;i<n;i++){
        cin>>id>>k;
        for(j=0;j<k;j++){
            cin>>gow>>weight;
            w[id][gow]=weight;
        }
    }
    dijkstra(w);
    for(i=0;i<n;i++){
        cout<<i<<" "<<d[i]<<endl;
    }
}

C++: #include<iostream>
#include<iomanip>
#include<map>
#include<set>
#include<string>
#include<algorithm>
#include<cmath>
#include<vector>
#include<queue>
#include<stack>
#include<cstring>
#include<sstream>
using namespace std;
 
#define P(p) cout<<(p)<<endl
#define rep(i,m,n) for(int i = (m); i < (int)(n); i++)
#define rrep(i,m,n) for(int i=(int)(m); i>=(int)(n); i--)
#define vsort(v) sort(v.begin(), v.end());
#define rvsort(v) sort(v.begin(), v.end(),greater<int>());
#define YES cout<<"YES"<< endl
#define NO cout<<"NO"<<endl
#define Yes cout<<"Yes"<<endl
#define No cout<<"No"<<endl  
#define yes cout<<"yes"<<endl
#define no cout<<"no"<<endl
#define ret return
#define lb(v,n) lower_bound(v.begin(),v.end(),n)
#define ub(v,n) upper_bound(v.begin(),v.end(),n)
#define mae(v) max_element(v.begin(),v.end())
#define mie(v) min_element(v.begin(),v.end())
#define mod 1000000007
typedef long long ll;
////////////////////////////////////////////////////////////

typedef struct edge_{
	int to,cost;
}edge;

class graph{ 
	typedef long cost_type;
	typedef int edge_type;
	typedef pair<cost_type,edge_type> P; 	//first:最短経路コスト second:頂点番号
	
	
	private:
		vector<vector<edge> > gra; 	//グラフ本体
		priority_queue<P,vector<P>,greater<P> > que; 	//最短経路の値の小さいものから取り出せる
		edge_type V; 	//頂点の個数
	  vector<cost_type> dp; 	//開始地点からの最小コストを格納する配列
	
	public:
		void init(int num){
			V = num;
			dp.assign(V,0x7FFFFFFF);
			gra.assign(V,vector<edge>());
		}


		void setCost(edge_type from , edge_type to , edge_type cost){
			edge e = {to , cost};
			edge e2 = {from , cost};
			gra[from].push_back( e );
			gra[to].push_back(e2);
		}	

		
		void setDirectCost(edge_type from , edge_type to , edge_type cost){
			edge e = {to , cost};
			gra[from].push_back( e );
		}	


		void dijkstra(edge_type s){
			dp[s] = 0;
			que.push(pair<cost_type,edge_type>(0,s)); 

			while(!que.empty()){
				P p = que.top();
				que.pop();
				edge_type v = p.second;
				if( dp[v] > p.first ) continue;
				for(edge_type i = 0 ; i < gra[v].size() ; i++ ){
					edge e = gra[v][i];
					if( dp[e.to] > dp[v] + e.cost ){
						dp[e.to] = dp[v] + e.cost;
						que.push(pair<cost_type,edge_type>(dp[e.to],e.to));
					}
				}
			}
		}

		cost_type getCost(edge_type to){
			return dp[to];
		} 

};

int main(){
	graph g;
	int n;
	cin >> n;
	g.init(n);
	rep(i,0,n){
		int from , k;
		cin >> from >> k;
		rep(i,0,k){
			int to;
			long cost;
			cin >> to >> cost;
			g.setDirectCost(from,to,cost);
		}

	}

	g.dijkstra(0);

	rep(i,0,n)
		cout << i << " " << g.getCost(i) << endl;

	ret 0;
}