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 <stdio.h>
#include <vector>

using namespace std;

struct Info{
	Info(int arg_weight,short arg_to){
		weight = arg_weight;
		to = arg_to;
	}
	int weight;
	short to;
};


int main(){
	int n,count=0,t,min,min_index,tmp,left_node,right_node,dist,t_to_i;
	scanf("%d",&n);
	vector<Info> V[n];

	int P[n],zero_dist[n];

	for(int i=0;i<n;i++){
		P[i]=0;
		zero_dist[i] = 10000001;
	}
	zero_dist[0] = 0;
	P[0]=1;

	for(int i=0;i<n;i++){
		scanf("%d %d",&left_node,&tmp);
		if(left_node == 0){
			for(int k=0;k<tmp;k++){
				scanf("%d %d",&right_node,&dist);
				zero_dist[right_node] = dist;
			}
		}else{
			for(int k=0;k<tmp;k++){
				scanf("%d %d",&right_node,&dist);
				V[left_node].push_back(Info(dist,right_node));
			}
		}
	}

	while(count<n-1){

		min=10000001;
		for(int i=1;i<n;i++){
			if(P[i]==0&&zero_dist[i]<min){
				min_index = i;
				min = zero_dist[i];
			}
		}
		t = min_index;
		P[t]=1;
		count++;

		for(int i=1;i<n;i++){
			t_to_i = 10000001;
			for(int k=0;k<V[t].size();k++){
				if(V[t][k].to == i){
					t_to_i = V[t][k].weight;
					break;
				}
			}
			if(zero_dist[i] > zero_dist[t]+t_to_i){
				zero_dist[i]=zero_dist[t]+t_to_i;
			}
		}
	}

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

    return 0;
}

C++: //
//  main.cpp
//
//
//  Created by ???????????? on 2017/10/23.
//  Copyright ?? 2017 ????????????. All rights reserved.
//

#include <iostream>
#include <stdio.h>
#include <queue>
#include <algorithm>


#define n_max 100
#define WHITE 0
#define GRAY 1
#define BLACK 2
#define INFTY 1<<20

using namespace std;

int n, M[n_max][n_max], color[n_max], d[n_max], p[n_max];

void init(){
    int i, j, id, num, node;
    scanf("%d", &n);
    for(i = 0; i < n; i++){
        for(j = 0; j < n; j++){
            M[i][j] = INFTY;
        }
    }
    
    
    for(i = 0; i < n; i++){
        scanf("%d %d", &id, &num);
        for(j = 0; j < num; j++){
            scanf("%d", &node);
            scanf("%d", &M[id][node]);
        }
        color[i] = WHITE;
        d[i] = INFTY;
    }
}

void dijkstra(){
    //initializing
    d[0] = 0;
    p[0] = -1;
    
    priority_queue<pair<int, int>> PQ;
    
    PQ.push(make_pair(0, 0));
    
    int u;
    while(!PQ.empty()){
        //first weight, second idx
        pair<int, int> f= PQ.top(); PQ.pop();
        u = f.second;
        color[u] = BLACK;
        
        if(d[u] < f.first*(-1)) continue;
        
        for(int v = 0; v < n; v++){
            if((color[v] != BLACK) && (M[u][v] != INFTY)){
                if((d[u] + M[u][v]) < d[v]){
                    d[v] = M[u][v] + d[u];
                    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 argc, const char * argv[]) {
    init();
    dijkstra();
    return 0;
}

C++: #include <climits>
#include <functional>
#include <iostream>
#include <queue>
#include <utility>
#include <vector>
using namespace std;

int main() {
	int n, u, k, v, c;
	cin >> n;
	vector<vector<pair<int, int>>> a(n);
	for (int i = 0; i < n; ++i) {
		cin >> u >> k;
		for (int j = 0; j < k; ++j) {
			cin >> v >> c;
			a[u].emplace_back(v, c);
		}
	}
	priority_queue<pair<int, int>, vector<pair<int, int>>, greater<pair<int, int>>> b;
	b.emplace(0, 0);
	vector<bool> d(n);
	vector<int> e(n, INT_MAX);
	e[0] = 0;
	while (!b.empty()) {
		pair<int, int> f = b.top();
		b.pop();
		d[f.second] = true;
		for (int i = 0; i < a[f.second].size(); ++i) {
			if (!d[a[f.second][i].first]) {
				if (a[f.second][i].second + e[f.second] < e[a[f.second][i].first]) {
					e[a[f.second][i].first] = a[f.second][i].second + e[f.second];
					b.emplace(e[a[f.second][i].first], a[f.second][i].first);
				}
			}
		}
	}
	for (int i = 0; i < n; ++i) cout << i << ' ' << e[i] << endl;
}

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

#define INF 100000000

typedef struct state {
  int pos, cost;
} state;

state A[2000001];
int N = 0;

int parent (int i) { return i/2;}
int left ( int i) {return i * 2;}
int right ( int i ) {return i * 2 + 1;}

void swap( state* a, state* b ) {
  state tmp = *a;
  *a = *b;
  *b = tmp;
}

void minHeapify ( int i ) {
  int l = left(i);
  int r = right(i);
  int small;

  if ( l <= N && A[l].cost < A[i].cost ) small = l;
  else small = i;

  if ( r <= N && A[r].cost < A[small].cost ) small = r;

  if ( small != i ) {
    swap ( &A[i], &A[small] );
    minHeapify(small);
  }
}

state heapExtractMin() {
  if ( N < 1 ) return (state) {0,0};
  state min = A[1];
  A[1] = A[N];
  N--;
  minHeapify(1);
  return min;
}

void heapIncreaseKey( int i , state key ) {
  if ( key.cost > A[i].cost) return;

  A[i] = key;
  while ( i > 1 && A[parent(i)].cost > A[i].cost ) {
    swap( &A[i], &A[parent(i)]);
    i = parent(i);
  }
}

void minHeapInsert( state key ) {
  N++;
  A[N] = (state) { INF, INF };
  heapIncreaseKey(N, key);
}

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

edge* G[10000];
int size[10000];
int n;
int d[10000];
edge e;
state s;

int main() {
  int a,b;
  cin >> n;
  for ( int i = 0; i < n; i++ ) {
    cin >> a >> b;
    G[a] = (struct edge*)malloc( sizeof(edge )*b );
    size[a] = b;
    for ( int j = 0; j < b; j++ ) {
      cin >> G[a][j].to >> G[a][j].cost;
    }
    d[i] = INF;
  }
  d[0] = 0;
  minHeapInsert ( (state{0,0} ) );
  while(N!=0) {
    s = heapExtractMin();
    if ( s.cost > d[s.pos]) continue;
    for ( int i = 0; i < size[s.pos]; i++ ) {
      e = G[s.pos][i];
      if ( d[e.to] <= d[s.pos] + e.cost ) continue;
      d[e.to] = d[s.pos] + e.cost;
      minHeapInsert((state){e.to,d[e.to]});
    }
  }
  for ( int i = 0; i < n; i++ ) {
    cout << i << " " << d[i] << endl;
  }
}