Go: package main

import (
	"fmt"
	"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)

	g := make([][]int, n)
	c := make([][]int, n)
	pq := make(PriorityQueue, 0, n)
	d := make([]int, n)
	for i := 0; i < n; i++ {
		var u,k int
		fmt.Scan(&u)
		fmt.Scan(&k)
		g[u] = make([]int, k)
		c[u] = make([]int, k)
		for j := 0; j < k; j++ {
			fmt.Scan(&g[u][j])
			fmt.Scan(&c[u][j])
		}

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

	for i := 0; i < n; i++ {
		fmt.Println(i, d[i])
	}
}

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