Go: package main

import (
	"fmt"
	"bufio"
	"os"
	"strconv"
	"container/heap"
)

type Node struct {
	Id int
	Dis int
}

type PriorityQueue []*Node

func (pq PriorityQueue) Len() int { return len(pq) }

func (pq PriorityQueue) Less(i, j int) bool {
	return pq[i].Dis < pq[j].Dis
}

func (pq PriorityQueue) Swap(i, j int) {
	pq[i], pq[j] = pq[j], pq[i]
}

func (pq *PriorityQueue) Push(x interface{}) {
	*pq = append(*pq, x.(*Node))
}

func (pq *PriorityQueue) Pop() interface{} {
	n := len(*pq)
	pop := (*pq)[n-1]
	*pq = (*pq)[0:n-1]
	return pop
}

func main() {
	var n int
	fmt.Scan(&n)

	sc := bufio.NewScanner(os.Stdin)
	sc.Split(bufio.ScanWords)

	g := make([][]int, n)
	c := make([][]int, n)
	pq := make(PriorityQueue, 0, n)
	d := make([]int, n)
	for i := 0; i < n; i++ {
		sc.Scan()
		u, _ := strconv.Atoi(sc.Text())
		sc.Scan()
		k, _ := strconv.Atoi(sc.Text())
		g[u] = make([]int, k)
		c[u] = make([]int, k)
		for j := 0; j < k; j++ {
			sc.Scan()
			g[u][j], _ = strconv.Atoi(sc.Text())
			sc.Scan()
			c[u][j], _ = strconv.Atoi(sc.Text())
		}

		if u == 0 {
			d[u] = 0
		} else {
			d[u] = 1 << 30
		}
		pq.Push(&Node{u, d[u]})
	}
	heap.Init(&pq)

	for pq.Len() > 0 {
		node := heap.Pop(&pq).(*Node)
		for i := 0; i < len(g[node.Id]); i++ {
			nextId := g[node.Id][i]
			nextDis := node.Dis + c[node.Id][i]
			if nextDis < d[nextId] {
				d[nextId] = nextDis
				heap.Push(&pq, &Node{nextId, nextDis})
			}
		}
	}

	wr := bufio.NewWriter(os.Stdout)
	for i := 0; i < n; i++ {
		wr.WriteString(strconv.Itoa(i))
		wr.WriteString(" ")
		wr.WriteString(strconv.Itoa(d[i]))
		wr.WriteString("\n")
	}
	wr.Flush()
}

C++: #include <iostream>
#include <algorithm>
#include <queue>
using namespace std;
#define MAX 10000
#define INFTY (1<<20)
#define WHITE 0
#define GRAY 1
#define BLACK 2

int n;
vector<pair<int, int> > adj[MAX];
void dijkstra()
{
    priority_queue<pair<int, int> >PQ;
    int color[MAX];
    int d[MAX];
    for(int i=0; i<n; i++)
    {
        d[i] = INFTY;
        color[i] = WHITE;
    }
    d[0] = 0;
    PQ.push(make_pair(0,0));
    color[0] = GRAY;
    while(!PQ.empty())
    {
        pair<int, int> f = PQ.top();
        PQ.pop();
        int u = f.second;
        color[u] = BLACK;
        if(d[u] < f.first*(-1))   continue;
        for(int j=0; j<adj[u].size(); j++)
        {
            int v = adj[u][j].first;
            if(color[v] == BLACK)
                continue;
            if(d[v]>d[u]+adj[u][j].second)
            {
                d[v] = d[u]+adj[u][j].second;
                PQ.push(make_pair(d[v]*(-1),v));
                color[v] = GRAY;
            }
        }
    }
    for(int i=0; i<n; i++)
        cout << i << " " << d[i] << endl;
}
int main()
{
    int k, u, v, c;
    cin >> n;
    for(int i=0; i<n; i++)
    {
        cin >> u >> k;
        for(int j=0; j<k; j++)
        {
            cin >> v >> c;
            adj[u].push_back(make_pair(v,c));
        }
    }
    dijkstra();
    return 0;
}

C++: #include<iostream>
using namespace std;
static const int MAX = 100;
static const int INFTY = (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 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];
			}
		}
		if (u == -1) break;
		color[u] = BLACK;
		for (int v = 0; v < n; v++) {
			if (color[v] != BLACK&&M[u][v] != INFTY) {
				if (d[v] > d[u] + M[u][v]) {
					d[v] = d[u] + M[u][v];
					color[v] = GRAY;
				}
			}
		}
	}
	for (int i = 0; i < n; i++) {
		cout << i << " " << (d[i] == INFTY ? -1 : 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 <iostream>
#include <cstdio>
#include <vector>
#include <climits>

class Graph{
public:
	std::vector< std::vector<std::vector<int> > > A;
	int n;

	Graph(int n);

	void SetEdge(int a, int b, int weight);
	void SortEdge();
	void SortEdge_Rec1(int left, int right);
	void SortEdge_Rec2(int left, int mid, int right);

	std::vector<int> Dijkstra();

};

Graph::Graph(int n){
	A.resize(n);
	this->n = n;
}

void Graph::SetEdge(int a, int b, int weight){
	std::vector<int> x(2);
	x[0] = b; x[1] = weight;
	A[a].push_back(x);
	return;
}

std::vector<int> Graph::Dijkstra(){
	std::vector<int> d(n, INT_MAX), prev(n, -1), Q(n, 0);
	d[0] = 0;
	for (int i = 0; i < n; i++) Q[i] = i;

	while (!Q.empty()){
		int mini, minu;
		for (int i = 0; i < (int)Q.size(); i++){
			if (i == 0 || d[Q[i]] < d[minu]){
				minu = Q[i];
				mini = i;
			}
		}
		Q.erase(Q.begin() + mini);
		for (int i = 0; i < (int)A[minu].size(); i++){
			if (d[A[minu][i][0]] > d[minu] + A[minu][i][1]){
				d[A[minu][i][0]] = d[minu] + A[minu][i][1];
				prev[A[minu][i][0]] = minu;
			}
		}
	}
	return d;
}

int main(){
	int n, u, k, v, c;
	scanf("%d", &n);
	Graph G(n);
	for (int i = 0; i < n; i++){
		scanf("%d%d", &u, &k);
		for (int j = 0; j < k; j++){
			scanf("%d%d", &v, &c);
			G.SetEdge(u, v, c);
		}
	}
	std::vector<int> result = G.Dijkstra();
	for (int i = 0; i < n; i++) printf("%d %d\n", i, result[i]);

	return 0;
}

C++: #include <queue>
#include <stdint.h>
#include <vector>

typedef void (*single_source_shortest_path_callback_t)(int32_t index, int32_t weight);

#define GRAPH_MAX_SIZE 10000
extern bool single_source_shortest_path(vector<pair<int32_t, int32_t>> *graph, size_t size,
                                        single_source_shortest_path_callback_t callback);

enum color_t { WHITE, GRAY, BLACK };

static int32_t weights[GRAPH_MAX_SIZE];
static color_t colors[GRAPH_MAX_SIZE];

bool single_source_shortest_path(vector<pair<int32_t, int32_t>> *graph, size_t size, single_source_shortest_path_callback_t callback)
{
  if ((graph == nullptr) || (size == 0)) return false;

  int32_t i;
  for (i = 0; i < GRAPH_MAX_SIZE; i++) {
    weights[i] = INT32_MAX;
    colors[i] = WHITE;
  }

  weights[0] = 0;
  priority_queue<pair<int32_t, int32_t>> que;
  que.push(make_pair(-1 * weights[0], 0));

  while (!que.empty()) {
    pair<int, int> top = que.top();
    que.pop();
    int32_t top_index = top.second;
    int32_t top_weights = (-1) * top.first;
    if (top_weights > weights[top_index]) continue;

    callback(top_index, top_weights);
    colors[top_index] = BLACK;

    vector<pair<int32_t, int32_t>> vertex = graph[top_index];
    for (auto connect_to = vertex.begin(); connect_to != vertex.end(); connect_to++) {
      int32_t index = (*connect_to).first;
      if (colors[index] != BLACK) {
        int32_t new_weight = weights[top_index] + (*connect_to).second;

        if (new_weight < weights[index]) {
          weights[index] = new_weight;
          colors[index] = GRAY;
          que.push(make_pair(-1 * weights[index], index));
        }
      }
    }
  }
  return true;
}

#if !defined(TEST)
static vector<pair<int32_t, int32_t>> graph[GRAPH_MAX_SIZE];
static int32_t routes[GRAPH_MAX_SIZE];

void callback(int32_t index, int32_t weight)
{
  routes[index] = weight;
}

int32_t main(void)
{
  int32_t num;
  scanf("%d", &num);

  uint32_t i;
  for (i = 0; i < num; i++) {
    int32_t index, len;
    scanf("%d", &index);
    scanf("%d", &len);
    uint32_t j;
    for (j = 0; j < len; j++) {
      int32_t k, v;
      scanf("%d %d", &k, &v);
      graph[i].push_back(make_pair(k, v));
    }
  }
  single_source_shortest_path(graph, num, callback);

  for (i = 0; i < num; i++) {
    printf("%d %d\n", i, routes[i]);
  }

  return 0;
}
#endif