Go: package main

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

func getScanner(fp *os.File) *bufio.Scanner {
	scanner := bufio.NewScanner(fp)
	scanner.Split(bufio.ScanWords)
	scanner.Buffer(make([]byte, 500001), 500000)
	return scanner
}

func getNextString(scanner *bufio.Scanner) string {
	scanner.Scan()
	return scanner.Text()
}

func getNextInt(scanner *bufio.Scanner) int {
	i, _ := strconv.Atoi(getNextString(scanner))
	return i
}

func main() {
	fp := os.Stdin
	if len(os.Args) > 1 {
		fp, _ = os.Open(os.Args[1])
	}

	scanner := getScanner(fp)
	writer := bufio.NewWriter(os.Stdout)

	n := getNextInt(scanner)

	g := makeGraph(n)
	for i := 0; i < n; i++ {
		u := getNextInt(scanner)
		k := getNextInt(scanner)
		for ii := 0; ii < k; ii++ {
			v := getNextInt(scanner)
			c := getNextInt(scanner)
			g[u][v] = c
		}
	}

	ans := make([]int, n)
	im := make(IntMap, 1)
	im.increment(0)
	for len(im) < n {
		min := 1 << 30
		x := -1
		for u := range im {
			for v := 0; v < n; v++ {
				if im.get(v) != 0 {
					continue
				}
				if min > ans[u]+g[u][v] {
					min = ans[u] + g[u][v]
					x = v
				}
			}
		}
		im.increment(x)
		ans[x] = min
	}

	for i := 0; i < n; i++ {
		fmt.Fprintln(writer, fmt.Sprintf("%d %d", i, ans[i]))
	}
	writer.Flush()
}

func makeGraph(n int) [][]int {
	g := make([][]int, n)
	for i := 0; i < n; i++ {
		g[i] = make([]int, n)
		for ii := 0; ii < n; ii++ {
			g[i][ii] = 1 << 30
		}
	}

	return g
}

// IntMap ...
type IntMap map[int]int

func (m IntMap) get(key int) int {
	if _, ok := m[key]; ok {
		return m[key]
	}
	return 0
}
func (m IntMap) increment(key int) {
	if _, ok := m[key]; ok == false {
		m[key] = 0
	}
	m[key]++
}

C++: #include<iostream>
using namespace std;
static const int MAX = 100;
static const int INFTY = 1000001;
static const int WHITE = 0;
static const int GRAY = 1;
static const int BLACK = 2;

//Mは隣接行列
int n, M[MAX][MAX];


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

    for(int i=0; i<n; i++){
        d[i] = INFTY;
        color[i] = WHITE;
    }
    d[0] = 0;
    color[0] = GRAY;
    while(1){
        minv = INFTY;
        int u = -1;
        for(int i=0; i<n; i++){
            if(minv > d[i] && color[i] != BLACK){
                u = i;
                minv = d[i];
            }
        }
        //cout << "u=" << u << endl;
        if(u == -1) break;
        color[u] = BLACK;
        //d[i]にBLACkからiへの最短経路を入れる
        for(int i=0;  i<n; i++){
            if(color[i]!=BLACK) d[i] = min(M[u][i]+d[u], d[i]);
        }
    }
    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] = INFTY;
        }
    }

    int k, c, u, v;
    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();
     return 0;
}

C++: #include <cstdio>
#include <set>
#include <algorithm>
#include <cstring>

#define INF 1000000
using namespace std;

struct edge
{
  int to, nxt, w;
};

edge E[500005];
int head[10005], cnt = 0, dist[10005];
void add_edge(int u, int v, int w)
{
  E[cnt].to = v;
  E[cnt].w = w;
  E[cnt].nxt = head[u];
  head[u] = cnt++;
}

void dijkstra(int src)
{
  set <pair <int, int> > setds;
  for (int i = 0; i < 10005; i++)
  {
    dist[i] = INF;
  }
  setds.insert(make_pair(0, src));
  dist[src] = 0;
  while (!setds.empty())
  {
    pair<int, int> tmp = *(setds.begin());
    setds.erase(setds.begin());
    int u = tmp.second;
    for (int e = head[u]; ~e; e = E[e].nxt)
    {
      int v = E[e].to;
      int w = E[e].w;
      if (dist[v] > dist[u] + w)
      {
        if (dist[v] != INF)
        {
          setds.erase(setds.find(make_pair(dist[v], v)));
        }
        dist[v] = dist[u] + w;
        setds.insert(make_pair(dist[v], v));
      }
    }
  }
}

int main()
{
  memset(head, -1, sizeof(head));

  int n;
  scanf("%d", &n);
  for (int i = 0; i < n; i++)
  {
    int v, deg;
    scanf("%d%d", &v, &deg);
    for (int j = 0; j < deg; j++)
    {
      int to, cost;
      scanf("%d%d", &to, &cost);
      add_edge(v, to, cost);
    }
  }
  dijkstra(0);
  for (int i = 0; i < n; i++)
  {
    printf("%d %d\n", i, dist[i]);
  }
}

C++: #include <cstdint>
#include <vector>

using namespace std;

#define GRAPH_SIZE 100
#define WEIGHT_MAX 100001

enum state_t {
  WHITE,
  GRAY,
  BLACK,
};

static uint32_t graph[GRAPH_SIZE][GRAPH_SIZE];
static state_t state[GRAPH_SIZE];
static uint32_t dist[GRAPH_SIZE];

size_t single_source_shotest_path(size_t num)
{
  size_t cost = 0;

  for (uint32_t i = 0; i < num; i++) {
    state[i] = WHITE;
    dist[i] = WEIGHT_MAX;
  }

  state[0] = GRAY;
  dist[0] = 0;

  while (true) {
    size_t minimum_cost = WEIGHT_MAX;
    uint32_t to = 0;
    for (uint32_t i = 0; i < num; i++) {
      if ((dist[i] < minimum_cost) && (state[i] != BLACK)) {
        minimum_cost = dist[i];
        to = i;
      }
    }

    if (minimum_cost == WEIGHT_MAX) break;

    cost += minimum_cost;
    state[to] = BLACK;

    for (uint32_t i = 0; i < num; i++) {
      if (((dist[to] + graph[to][i]) < dist[i]) && state[i] != BLACK) {
        state[i] = GRAY;
        dist[i] = dist[to] + graph[to][i];
      }
    }
  }

  return cost;
}

#include <iostream>

int32_t main()
{
  uint32_t num;
  cin >> num;

  for (uint32_t i = 0; i < num; i++) {
    for (uint32_t j = 0; j < num; j++) {
      graph[i][j] = WEIGHT_MAX;
    }
  }

  for (uint32_t i = 0; i < num; i++) {
    uint32_t index, len;
    cin >> index >> len;
    for (uint32_t j = 0; j < len; j++) {
      uint32_t v, c;
      cin >> v >> c;
      graph[index][v] = c;
    }
  }

  single_source_shotest_path(num);

  for (uint32_t i = 0; i < num; i++) {
    cout << i << " " << dist[i] << endl;
  }

  return 0;
}