Go: package main

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

type Item struct {
	value    int // The value of the item; arbitrary.
	priority int // The priority of the item in the queue.
	// The index is needed by update and is maintained by the heap.Interface methods.
	index int // The index of the item in the heap.
}
type PriorityQueue []*Item

func (pq PriorityQueue) Len() int { return len(pq) }
func (pq PriorityQueue) Less(i, j int) bool {
	return pq[i].priority < pq[j].priority
}
func (pq PriorityQueue) Swap(i, j int) {
	pq[i], pq[j] = pq[j], pq[i]
	pq[i].index = i
	pq[j].index = j
}
func (pq *PriorityQueue) Push(x interface{}) {
	n := len(*pq)
	item := x.(*Item)
	item.index = n
	*pq = append(*pq, item)
}
func (pq *PriorityQueue) Pop() interface{} {
	old := *pq
	n := len(old)
	item := old[n-1]
	item.index = -1 // for safety
	*pq = old[0 : n-1]
	return item
}

type Q struct {
	pq *PriorityQueue
	ds map[int]int // It has always same value as pq. For random access.
}

func newQ() *Q {
	pq := new(PriorityQueue)
	heap.Init(pq)
	return &Q{
		pq: pq,
		ds: make(map[int]int),
	}
}
func (q *Q) pop() (u, d int) {
	item := heap.Pop(q.pq).(*Item)
	delete(q.ds, item.value)
	return item.value, item.priority
}
func (q *Q) get(u int) (int, bool) { // returns d
	d, ok := q.ds[u]
	return d, ok
}
func (q *Q) set(u, d int) {
	q.ds[u] = d
	for _, item := range *q.pq {
		if item.value != u {
			continue
		}

		item.priority = d
		heap.Fix(q.pq, item.index)
		return
	}
	heap.Push(q.pq, &Item{
		priority: d,
		value:    u,
	})
}
func (q *Q) len() int {
	return len(q.ds)
}

func main() {
	r := bufio.NewReader(os.Stdin)

	var n int
	fmt.Fscan(r, &n)
	cs := make([]map[int]int, n) // []v_i -> c_i
	for h := 0; h < n; h++ {
		var u, k int
		fmt.Fscan(r, &u, &k)
		m := make(map[int]int)
		for i := 0; i < k; i++ {
			var v, c int
			fmt.Fscan(r, &v, &c)
			m[v] = c
		}

		cs[u] = m
	}

	q := newQ()
	q.set(0, 0)
	visited := make(map[int]struct{})
	out := make([]int, n)

	for q.len() > 0 {
		u, d := q.pop()
		for uu, c := range cs[u] {
			// Consider the connection between u and uu.
			if _, ok := visited[uu]; ok {
				continue
			}
			dd := d + c
			if d, ok := q.get(uu); !ok || d > dd {
				q.set(uu, dd)
			}
		}

		out[u] = d
		visited[u] = struct{}{}
	}

	for u, d := range out {
		fmt.Println(u, d)
	}
}

C++: //ALDS1_12B
#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];

int dijkstra(){
 int minv;
 int d[MAX],color[MAX];
 for(int i=0;i<n;i++){
  d[i]=INF;
  color[i]=WHITE;
 }
 d[0]=0;
 color[0]=GRAY;
 while(true){
  minv=INF;
  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]!=INF){
    if(d[v]>M[u][v]){
     d[v]=d[u]+M[u][v];
     color[v]=GRAY;
    }
   }
  }
 }
 for(int i=0;i<n;i++){
  cout<<i<<" "<<(d[i]==INF ? -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]=INF;
  }
 }
 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 <bits/stdc++.h>
 
using namespace std;

namespace dijkstra_n {
template<class W>
struct Edge {
	using type = Edge<W>;
	int to;
	W w;
	template<class... Args> Edge(int t, Args... args) : to(t), w(args...) {}
	inline bool operator<(const Edge& rhs) const { return w < rhs.w; }
	inline bool operator>(const type& rhs) const { return rhs < *this; }
	inline bool operator>=(const type& rhs) const { return !(*this < rhs); }
	inline bool operator<=(const type& rhs) const { return !(rhs < *this); }
	inline bool operator==(const type& rhs) const { return !(*this < rhs) && !(rhs < *this); }
	inline bool operator!=(const type& rhs) const { return (*this < rhs) || (rhs < *this); }
};
template<class W>
struct Edges : private vector<vector<Edge<W>>> {
	using type = vector<vector<Edge<W>>>;
	template<class... Args> Edges(Args... args) : type(args...) {}
	template<class... Args> void add_edge(int u, int v, Args... args) {
		(*this)[u].emplace_back(v, args...);
	}
	using type::begin; using type::end; using type::rbegin; using type::rend;
	using type::cbegin; using type::cend; using type::crbegin; using type::crend;
	using type::size; using type::operator[]; using type::at; using type::back; using type::front;
	using type::reserve; using type::resize; using type::assign; using type::shrink_to_fit;
	using type::clear; using type::erase; using type::insert; using type::swap; 
	using type::push_back; using type::pop_back; using type::emplace_back; using type::empty;
};
template<class W>
struct Graph {
	const int sz;
	Edges<W> e;
	Graph(int n) : sz(n), e(sz) {}
	template<class... Args> void add_edge(int u, int v, Args... args) {
		e.add_edge(u, v, args...);
	}
	int size() {
		return sz;
	}
};
template<class W, class T = W>
struct Graph_D : public Graph<W> {
	vector<T> dist;
	Graph_D(int n) : Graph<W>(n), dist(n) {}
};
template<class W, class T>
void Dijkstra(Graph_D<W, T>& g, int start, T INF_COST) {
	auto& dist = g.dist;
	auto& e = g.e;
	for (auto& ww : dist) ww = INF_COST;
	using Q_T = pair<T, int>;
	priority_queue<Q_T, vector<Q_T>, greater<>> q;
	q.emplace(0, start);
	while (!q.empty()) {
		auto a = q.top();
		q.pop();
		if (a.first >= dist[a.second]) continue;
		dist[a.second] = a.first;
	for (auto& p : e[a.second]) {
			if (p.w == INF_COST) continue;
			if (a.first + p.w < dist[p.to]) q.emplace(a.first + p.w, p.to);
		}
	}
}
}
using dijkstra_n::Dijkstra;
template<class T, class U = T> using graph = dijkstra_n::Graph_D<T, U>;

int main() {
    int n; cin >> n;
    graph<int> g(n);
    for (int i = 0; i < n; i++) {
        int v, k; cin >> v >> k;
        while (k--) {
            int u, c; cin >> u >> c;
            g.add_edge(v, u, c);
        }
    }
    Dijkstra(g, 0, INT_MAX);
    for (int i = 0; i < n; i++) {
        cout << i << " " << g.dist[i] << endl;
    }
}

C++: /*
* @Author: Samson
* @Date:   2018-06-14 09:42:05
* @Last Modified by:   Samson
* @Last Modified time: 2018-06-14 10:06:32
*/
//   @URL : http://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=ALDS1_12_B
#include<bits/stdc++.h>
#include<algorithm>
#include <cstdlib>
#define INF 0x3f3f3f3f
using namespace std;
typedef long long LL;
const int MAXN = 1e3+10;

int a[MAXN][MAXN],n,d[MAXN],color[MAXN];

void dijkstra()
{
	memset(color,0,sizeof color);
	memset(d,INF,sizeof d);
	int s = 0,u,minv;
	d[s] = 0;
	while(1)
	{
		minv = INF;
		u = -1;
		for(int i = 0; i < n; ++i)
		{
			if(!color[i] && d[i] < minv)
				minv = d[i], u = i;
		}
		if(u == -1)	break;
		color[u] = 1;
		for(int v = 0; v < n; ++v)
		{
			if(!color[v] && a[u][v]!=INF)
			{
				if(d[u]+a[u][v] < d[v])
				{
					d[v] = d[u]+a[u][v];
				}
			}
		}
	}
	for(int i = 0; i < n; ++i)
		cout<<i<<' '<< (d[i]==INF?-1:d[i])<<'\n';
}
int main(void)
{
	ios::sync_with_stdio(false); 
	//cin.tie(0);
	int u,v,k,w;
	memset(a,INF,sizeof a);
	cin>>n;
	for(int i = 1; i <= n; ++i)
	{
		cin>>u>>k;
		for(int j = 1; j <= k; ++j)
		{
			cin>>v>>w;
			a[u][v] = w;
		}
	}
	dijkstra();
	return 0;
}