Go: package main

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

const NIL = -1

type Node struct {
	id     int
	weight int
}

func init() {
	sc.Split(bufio.ScanWords)
}

type NodeHeap []Node

func (h NodeHeap) Len() int           { return len(h) }
func (h NodeHeap) Less(i, j int) bool { return h[i].weight < h[j].weight }
func (h NodeHeap) Swap(i, j int)      { h[i], h[j] = h[j], h[i] }

func (h *NodeHeap) Push(x interface{}) {
	*h = append(*h, x.(Node))
}

func (h *NodeHeap) Pop() interface{} {
	old := *h
	n := len(old)
	x := old[n-1]
	*h = old[0 : n-1]
	return x
}

var sc = bufio.NewScanner(os.Stdin)

func scanInt() int {
	num, _ := strconv.Atoi(scanString())
	return num
}

func scanString() string {
	sc.Scan()
	return sc.Text()
}

func init() {
	sc.Split(bufio.ScanWords)
}

func main() {
	n := scanInt()

	list := make([][]int, n)
	weight := make([]int, n)
	for i := range list {
		list[i] = make([]int, n)
		weight[i] = NIL
		for j := range list[i] {
			list[i][j] = NIL
		}
	}

	for i := 0; i < n; i++ {
		u := scanInt()
		k := scanInt()
		for j := 0; j < k; j++ {
			v := scanInt()
			w := scanInt()
			list[u][v] = w
		}
	}

	start := Node{id: 0, weight: 0}
	h := &NodeHeap{start}
	heap.Init(h)

	for h.Len() > 0 {
		node := heap.Pop(h).(Node)
		if weight[node.id] != NIL {
			continue
		}
		weight[node.id] = node.weight

		for i, w := range list[node.id] {
			if w == NIL {
				continue
			}
			heap.Push(h, Node{id: i, weight: w + node.weight})
		}
	}

	w := bufio.NewWriter(os.Stdout)
	for i := 0; i < n; i++ {
		fmt.Fprint(w, i)
		fmt.Fprint(w, " ")
		fmt.Fprint(w, weight[i])
		fmt.Fprintln(w)
	}
	w.Flush()
}

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;
}

C++: #include<stdio.h>
#include<string.h>
int n, dis[105], a[105][105];
bool vst[105];
void dijkstra()
{
    memset(vst, 0, sizeof(vst));
    memset(dis, 0x3f3f3f3f, sizeof(dis));
    dis[0] = 0;
    for(int i = 0; i < n; i++)
    {
        int k = n;
        for(int j = 0; j < n; j++)
            if(!vst[j] && dis[k] > dis[j]) k = j;
        vst[k] = 1;
        for(int j = 0; j < n; j++)
            if(!vst[j] && dis[j] > dis[k] + a[k][j])
                dis[j] = dis[k] + a[k][j];
    }
}
int main()
{
    while(scanf("%d", &n) == 1)
    {
        memset(a, 0x3f3f3f3f, sizeof(a));
        for(int i = 1; i <= n; i++)
        {
            int m, j;
            scanf("%d%d", &m, &j);
            while(j--){
                int k, t;
                scanf("%d%d", &k, &t);
                if(t < a[m][k] || a[m][k] == -1) a[k][m] = a[m][k] = t;
            }
        }
        dijkstra();
        for(int i = 0; i < n; i++)
            printf("%d %d\n", i, dis[i]);        
    }
    return 0;
}

C++: #include "bits/stdc++.h"

using namespace std;

using ll = long long;
using ld = long double;

const int INF = (1 << 30) - 1;
const ll INF64 = ((ll)1 << 62) - 1;
const double PI = 3.1415926535897932384626433832795;

const int dx[] = { 0, 1, 0, -1 };
const int dy[] = { -1, 0, 1, 0 };

int main() {
	ios::sync_with_stdio(false);
	cin.tie(0);

	int n;
	cin >> n;

	vector<vector<pair<int, int>>> g(n);
	for (int i = 0; i < n; i++) {
		int k, v;
		cin >> k >> v;
		for (int j = 0; j < v; j++) {
			int u, c;
			cin >> u >> c;
			g[k].emplace_back(u, c);
		}
	}

	vector<int> dist(n, INF);
	dist[0] = 0;
	vector<bool> used(n);

	priority_queue<pair<int, int>, vector<pair<int, int>>, greater<pair<int, int>>> pq;
	pq.emplace(0, 0);
	while (!pq.empty()) {
		pair<int, int> p = pq.top(); pq.pop();
		int v = p.second;

		if (dist[v] < p.first) {
			continue;
		}

		for (auto e : g[v]) {
			int to = e.first;
			int cost = e.second;
			if (dist[to] > dist[v] + cost) {
				dist[to] = dist[v] + cost;
				pq.emplace(dist[to], to);
			}
		}
	}

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