Go: package main

import (
	"bufio"
	"bytes"
	"fmt"
	"io"
	"os"
	"strconv"
	"strings"
)

const (
	INFTY = 1 << 21
	NIL   = -1
)

const (
	WHITE = iota
	GRAY
	BLACK
)

type Graph [][]int

func (g *Graph) dikstra(n int) string {
	var (
		u, minv = 0, 0
	)

	d := make([]int, n)
	color := make([]int, n)

	for i := 0; i < n; i++ {
		d[i] = INFTY
		color[i] = WHITE
	}
	d[0] = 0
	color[0] = GRAY

	for {
		minv = INFTY
		u = -1
		for i := 0; i < n; i++ {
			if minv > d[i] && color[i] != BLACK {
				u = i
				minv = d[i]
			}
		}

		if u == -1 {
			break
		}

		color[u] = BLACK
		for v := 0; v < n; v++ {
			if color[v] != BLACK && (*g)[u][v] != INFTY {
				if d[v] > d[u]+(*g)[u][v] {
					d[v] = d[u] + (*g)[u][v]
					color[v] = GRAY
				}
			}
		}
	}

	var out bytes.Buffer
	for i := 0; i < n; i++ {
		out.WriteString(fmt.Sprintf("%d ", i))
		if d[i] == INFTY {
			out.WriteString(fmt.Sprintf("%d\n", -1))
			continue
		}
		out.WriteString(fmt.Sprintf("%d\n", d[i]))
	}

	return strings.TrimRight(out.String(), "\n")
}

func answer(reader io.Reader) string {
	sc := bufio.NewScanner(reader)
	sc.Split(bufio.ScanWords)

	sc.Scan()
	n, _ := strconv.Atoi(sc.Text())

	g := make(Graph, n)
	for i := 0; i < n; i++ {
		g[i] = make([]int, n)
		for j := 0; j < n; j++ {
			g[i][j] = INFTY
		}
	}

	for i := 0; i < n; i++ {
		sc.Scan()
		u, _ := strconv.Atoi(sc.Text())
		sc.Scan()
		k, _ := strconv.Atoi(sc.Text())

		for j := 0; j < k; j++ {
			sc.Scan()
			v, _ := strconv.Atoi(sc.Text())
			sc.Scan()
			c, _ := strconv.Atoi(sc.Text())

			g[u][v] = c
		}
	}

	return g.dikstra(n)
}

func main() {
	fmt.Println(answer(os.Stdin))
}

C++: #include<iostream>
using namespace std;

static const int MAX = 100;
static const int INF = (1<<21);
static const int WHITE = 0;
static const int GRAY = 1;
static const int BLACK = 2;

int n, M[MAX][MAX];

void dijkstra(){
    int d[MAX], color[MAX];
    int u, minc;

    for(int i = 0; i < n; i++){
        d[i] = INF;
        color[i] = WHITE;
    }

    d[0] = 0;

    while(1){
        minc = INF;
        u = -1;
        for(int i = 0; i < n; i++){
            if(color[i] != BLACK && minc > d[i]){
                minc = d[i];
                u = i;
            }
        }

        if(minc == INF) break;

        color[u] = BLACK;

        for(int v = 0; v < n; v++){
            if(M[u][v] != INF && color[v] != BLACK){
                if(d[u] + M[u][v] < d[v]){
                    d[v] = d[u] + M[u][v];
                    color[v] = GRAY;
                }
            }
        }
    }

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

int main(){
    cin >> n;

    for(int i = 0; i < n; i++){
        for(int j = 0; j < n; j++){
            M[i][j] = INF;
        }
    }

    for(int i = 0; i < n; i++){
        int from, k, to, c;
        cin >> from >> k;
        for(int j = 0; j < k; j++){
            cin >> to >> c;
            M[from][to] = c;
        }
    }

    dijkstra();

    return 0;
}

C++: #include<iostream>
#define INF 100000000
#define N 101
#define W 0
#define G 1
#define B 2
using namespace std;
int n,M[N][N],d[N];
void dijkstra(int s){
  int color[N],mincost,p[N],u;
  for(int i=0;i<n;i++) color[i]=W,d[i]=INF;
  d[s]=0;
  p[s]=-1;

  while(1){
    mincost=INF;
     u=-1;    
    for(int i=0;i<n;i++)
      if(color[i]!=B && d[i]<mincost){
	mincost=d[i];
	u=i;
      }
        if(mincost==INF) break;
        color[u]=B;
    for(int i=0;i<n;i++)
      if(color[i]!=B && M[u][i]!=INF)
	if(d[u]+M[u][i]<d[i]){
	  d[i]=d[u]+M[u][i];
	  p[i]=u;
	  color[i]=G;
	}
  }
}
int main(){
  int u,k,c,v;
  cin>>n;
  for(int i=0;i<N;i++) for(int j=0;j<N;j++)M[i][j]=INF;
  for(int i=0;i<n;i++){
    cin>>u>>k;
    for(int j=0;j<k;j++){
      cin>>v>>c;
    M[u][v]=c;
    }
  }
  dijkstra(0);
  for(int i=0;i<n;i++) cout<<i<<" "<<d[i]<<endl;
  return 0;
}

C++: #include <cstdio>
#include <iostream>
#include <string>
#include <vector>
#include <algorithm>
#include <queue>
using namespace std;

#define rep(i, n) for(int i = 0; i < n; ++i)
const int max_v = 10100;
const int max_e = 505000;
const int inf = 0x3fffffff;

typedef pair<int, int> P;

typedef struct edge {
    int to, dist;
    edge():to(0),dist(0) {}
    edge(int _to, int _dist):to(_to),dist(_dist) {}
    bool operator < (const edge & o) const {
	return dist > o.dist;
    }
}edge;

struct graph {
    int V, E;
    int d[max_v], prev[max_v];
    bool vis[max_v];
    vector<edge> G[max_v];
    graph():V(0),E(0) {}

    graph(int _V):V(_V),E(0) {}

    graph(int _V, int _E, int ed[][3], bool bidirect):V(_V),E(_E) {
	rep(i, E) {
	    int u = ed[i][0], v = ed[i][1], dist = ed[i][2];
	    G[u].push_back(edge(v, dist));
	    if (bidirect) G[v].push_back(edge(v, dist));
	}
    }
    graph(int _V, int g[][max_v]) {
	V = _V; E = 0;
	rep(i, V) rep(j, V)
	    if (g[i][j] != inf) {
		G[i].push_back(edge(j, g[i][j]));
		++E;
	    }
    }

    void add_edge(int u, int v, int c) {
	G[u].push_back(edge(v, c));
    }

    void output() {
	rep(i, V) {
	    printf("[%d] ", i);
	    rep(j, G[i].size()) {
		printf("(%d %d) ", G[i][j].to, G[i][j].dist);
	    }
	    putchar('\n');
	}
    }

    void dijkstra(int g[][max_v], int s) {
	rep(i, V) d[i] = inf;
	rep(i, V) prev[i] = -1;
	rep(i, V) vis[i] = false;

	d[s] = 0;
	rep(i, V) {
	    int tmp = inf;
	    int u = -1;
	    rep(j, V) {
		if(!vis[j] && d[j] < tmp) {
		    tmp = d[j];
		    u = j;
		}
	    }
	    vis[u] = true;
	    rep(j, V) {
		if(!vis[j] && d[u] + g[u][j] < d[j]) {
		    d[j] = d[u] + g[u][j];
		    prev[j] = u;
		}
	    }
	}
    }

    void dijkstra(int s) {
	rep(i, V) d[i] = inf;
	rep(i, V) prev[i] = -1;
	rep(i, V) vis[i] = false;
	
	priority_queue<edge> pq;
	pq.push(edge(s, 0));
	d[s] = 0;

	while(! pq.empty()) {
	    edge e = pq.top(); pq.pop();
	    if(e.dist > d[e.to]) continue;
	    d[e.to] = e.dist;
	    vis[e.to] = true;
	    
	    rep(j, G[e.to].size()) {
		int v = G[e.to][j].to;
		int dist = G[e.to][j].dist;

		if(!vis[v] && d[e.to] + dist < d[v]) {
		    d[v] = d[e.to] + dist;
		    prev[v] = e.to;
		    pq.push(edge(v, d[v]));
		}
	    }
	}
    }
};

int N, M;

void solve() {
    int u, k, v, c;
    scanf("%d", &N);
    graph g = graph(N);
    rep(i, N) {
	scanf("%d%d", &u, &k);
	rep(j, k) {
	    scanf("%d%d", &v, &c);
	    g.add_edge(u, v, c);
	}
    }
    g.dijkstra(0);
    rep(i, N) {
	printf("%d %d\n", i, g.d[i]);
    }
}

int main() {
    solve();
    return 0;
}

C++: #include <bits/stdc++.h>
using namespace std;

const int MAX=105;
int state[MAX],N,D[MAX];
vector<pair<int,int>> S[MAX];
priority_queue<pair<int,int>> Q;

void dijkstra(){
    int cnt=1;
    for(int i=0;i<N;i++){
        state[i]=0;
        D[i]=100000000;
    }
    state[0]=1;
    D[0]=0;
    for(int i=0;i<S[0].size();i++){
        Q.push(make_pair(-S[0][i].second,S[0][i].first));
        D[S[0][i].first]=min(D[S[0][i].first],D[0]+S[0][i].second);
    }
    while(1){
        int a=Q.top().second;
        cout<<a<<endl;
        if(state[a]==0){
            Q.pop();
            state[a]=1;
            cnt++;
            for(int i=0;i<S[a].size();i++){
                if(state[S[a][i].first]==0){
                    Q.push(make_pair(-S[a][i].second,S[a][i].first));
                    D[S[a][i].first]=min(D[S[a][i].first],D[a]+S[a][i].second);
                }
            }
        }
        else Q.pop();
        if(cnt==N) break;
    }
    return;
}


int main(){
    
    cin>>N;
    for(int i=0;i<N;i++){
        int l,a;cin>>l>>a;
        for(int j=0;j<a;j++){
            int b,c;cin>>b>>c;
            S[i].push_back(make_pair(b,c));
        }
    }
    dijkstra();
    for(int i=0;i<N;i++){
        cout<<i<<" "<<D[i]<<endl;
    }
}