Go: package main

import (
	"bufio"
	"fmt"
	"os"
	"strconv"
)

const (
	MAX_N      = 100
	MAX_WEIGHT = 100000
)

type Edge struct {
	start  int
	end    int
	weight int
}

type ShortestInfo struct {
	edges    []Edge
	shortest int
}

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

	n, err := nextInt(sc)
	if err != nil {
		panic(err)
	}

	shortestList := make([]ShortestInfo, n)
	for i := 1; i < n; i++ {
		shortestList[i] = ShortestInfo{edges: []Edge{}, shortest: MAX_N*MAX_WEIGHT + 1}
	}

	adjacentMatrix, err := createAdjacentMatrix(n, sc)
	if err != nil {
		panic(err)
	}

	sssp([]int{1}, shortestList, adjacentMatrix)
	for _, v := range shortestList {
		fmt.Printf("%d %d\n", v.getEnd()-1, v.shortest)
	}
}

func (si ShortestInfo) getEnd() int {
	if len(si.edges) == 0 {
		return 1
	} else {
		return si.edges[len(si.edges)-1].end
	}
}

func createAdjacentMatrix(n int, sc *bufio.Scanner) ([][]int, error) {
	adjacentMatrix := make([][]int, n)
	for i := 0; i < n; i++ {
		id, err := nextInt(sc)
		if err != nil {
			return nil, err
		}
		adjacentMatrix[id] = make([]int, n)
		for j := 0; j < n; j++ {
			adjacentMatrix[id][j] = -1
		}
		vertexNum, err := nextInt(sc)
		if err != nil {
			return nil, err
		}
		for j := 0; j < vertexNum; j++ {
			v, err := nextInt(sc)
			if err != nil {
				return nil, err
			}
			c, err := nextInt(sc)
			if err != nil {
				return nil, err
			}
			adjacentMatrix[id][v] = c
		}
	}
	return adjacentMatrix, nil
}

func sssp(nodeStack []int, shortestList []ShortestInfo, adjacentMatrix [][]int) {
	for len(nodeStack) > 0 {
		currentNode := nodeStack[0]
		nodeStack = nodeStack[1:]
		currentShortest := getShortest(currentNode, shortestList)
		adjacents := findAdjacents(currentNode, adjacentMatrix)
		for i := 0; i < len(adjacents); i++ {
			adj := adjacents[i]
			if currentShortest.shortest+adj.weight < getShortest(adj.end, shortestList).shortest {
				setShortest(adj.end, adj, currentShortest, shortestList)
				nodeStack = append(nodeStack, adj.end)
			}
		}
	}
}

func getShortest(node int, shortestList []ShortestInfo) ShortestInfo {
	return shortestList[node-1]
}

func setShortest(node int, edge Edge, currentShortest ShortestInfo, shortestList []ShortestInfo) {
	newEdges := make([]Edge, len(currentShortest.edges)+1)
	for i := 0; i < len(newEdges)-1; i++ {
		newEdges[i] = currentShortest.edges[i]
	}
	newEdges[len(newEdges)-1] = edge
	shortestInfo := ShortestInfo{edges: newEdges, shortest: currentShortest.shortest + edge.weight}
	shortestList[node-1] = shortestInfo
}

func findAdjacents(currentNode int, adjacentMatrix [][]int) []Edge {
	adjacents := adjacentMatrix[currentNode-1]
	edges := []Edge{}
	for i, v := range adjacents {
		if v > 0 {
			edges = append(edges, Edge{start: currentNode, end: i + 1, weight: v})
		}
	}
	return edges
}

func nextInt(sc *bufio.Scanner) (int, error) {
	sc.Scan()
	return strconv.Atoi(sc.Text())
}

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