Go: package main

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

const BIG_COST = 200000

const (
	ST_NOT_YET = iota
	ST_JOINED
)

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

	nNodes := scanInt(sc)

	costs := make([][]int, nNodes)
	graph := make([][]int, nNodes)

	states := make([]int, nNodes)
	costSums := make([]int, nNodes)

	for i := 0; i < nNodes; i++ {
		costs[i] = make([]int, nNodes)
		costSums[i] = BIG_COST
	}

	for i := 0; i < nNodes; i++ {
		u := scanInt(sc)
		k := scanInt(sc)
		graph[u] = make([]int, k)
		for d := 0; d < k; d++ {
			v := scanInt(sc)
			graph[u][d] = v
			costs[u][v] = scanInt(sc)
		}
	}

	costSums[0] = 0
	for {
		minCost := BIG_COST
		var u int

		for i, cost := range costSums {
			if states[i] != ST_JOINED && cost < minCost {
				minCost = cost
				u = i
			}
		}

		if minCost == BIG_COST {
			break
		}

		states[u] = ST_JOINED

		for _, v := range graph[u] {
			cost := minCost + costs[u][v]
			if cost < costSums[v] {
				costSums[v] = cost
			}
		}
	}

	w := bufio.NewWriter(os.Stdout)
	for i, cost := range costSums {
		fmt.Fprintf(w, "%d %d\n", i, cost)
	}
	w.Flush()
}

func scanInt(sc *bufio.Scanner) int {
	sc.Scan()
	v, _ := strconv.Atoi(sc.Text())
	return v
}

C++: #include<bits/stdc++.h>
#include<limits.h>
using namespace std;
#define rep(i, n) for(int i = 0; i < n; i++)

#define MAX 101
#define INF INT_MAX

vector<vector<int>> adj_mat(MAX, vector<int>(MAX, INT_MAX));

void dijkstra(int start_node, int node_size){
    vector<int> visited(node_size, 0);
    vector<int> cost_table(node_size, INF);

    int node = start_node;
    cost_table.at(node) = 0;

    while(true){
        // cout << "looking node : " << node << ",  cost : ";
        // rep(i, node_size){
        //     cout << cost_table.at(i) << " "; 
        // }
        // cout << endl;

        visited.at(node) = 1;

        rep(i, node_size){
            if(visited.at(i) == 0 && adj_mat.at(node).at(i) != INF){
                int new_cost = adj_mat.at(node).at(i) + cost_table.at(node);
                if(new_cost < cost_table.at(i)){
                    cost_table.at(i) = new_cost;
                }
            }
        }

        int m = INF;
        rep(i, node_size){
            if(visited.at(i) == 0 && (cost_table.at(i) < m)){
                m = cost_table.at(i);
                node = i;
            }
        }
        if(m == INF){
            break;
        }
    }

    rep(i, node_size){
        cout << i << " " << cost_table.at(i) << endl;
    }

}

int main(){
    int n; cin >> n;
    rep(i, n){
        int u, k; cin >> u >> k;
        rep(j, k){
            int v, c; cin >> v >> c;
            adj_mat.at(u).at(v) = c;
        }
    }

    // rep(i, n){
    //     rep(j, n){
    //         if(adj_mat.at(i).at(j) == INT_MAX) cout << "∞ ";
    //         else cout << adj_mat.at(i).at(j) << " ";
    //     }
    //     cout << endl;
    // }

    dijkstra(0, n);

}

C++: // -*- mode:c++; coding:utf-8; c-basic-offset:2; -*-
// ALDS1_12_B: Single Source Shortest Path I

#include <algorithm>
#include <cstdio>

using uint = unsigned int;

class Graph {
  const uint n_;
  uint* const g_;
  
public:
  const static uint INFINIT = 100000+1;

  Graph(uint n) : n_(n), g_(new uint[(n_*n_)]) { std::fill_n(g_, (n_*n_), INFINIT); }

  ~Graph() { delete[] g_; }
  
  uint* operator [](uint i) const { return g_+(n_*i); }

  void dijkstra(uint* dist)
  {
    std::fill_n(dist, n_, INFINIT);
    bool visited[n_];
    std::fill_n(visited, n_, false);
    auto i = 0u; // 0-start
    visited[i] = true;
    dist[i] = 0u;
    for (auto n = 0u; n < n_-1; ++n) {
      auto cur_min_dist = INFINIT;
      auto es = (*this)[i];
      auto base_dist = dist[i];
      for (auto j = 0u; j < n_; ++j) {
        if (visited[j]) continue;
        dist[j] = std::min(dist[j], base_dist+es[j]);
        if (cur_min_dist > dist[j]) {
          cur_min_dist = dist[j];
          i = j;
        }
      }
      visited[i] = true;
      dist[i] = cur_min_dist;
    }
  }
};

const uint Graph::INFINIT;

int main()
{
  uint n;
  std::scanf("%u", &n);

  Graph g(n);

  uint u, k, c, v;
  for (auto i = 0u; i < n; ++i) {
    std::scanf("%u %u", &u, &k);
    for (auto j = 0u; j < k; ++j) {
      std::scanf("%u %u", &c, &v);
      g[u][c] = v;
    }
  }

  uint dist[n];
  g.dijkstra(dist);
  for (auto i = 0u; i < n; ++i) {
    std::printf("%u %u\n", i, dist[i]);
  }
}

// eof

C++: import java.util.ArrayList;
import java.util.Arrays;
import java.util.PriorityQueue;
import java.util.Scanner;

public class Main {
    int[] distTo = null;
    int[] parentOf = null;

    public Main(ArrayList<ArrayList<Edge>> G){
        distTo = new int[G.size()];
        Arrays.fill(distTo, Integer.MAX_VALUE);
        parentOf = new int[G.size()];

        PriorityQueue<SDto> pq = new PriorityQueue<>();

        pq.add(new SDto(0, 0, -1));
        while (!pq.isEmpty()) {

            SDto optim = pq.poll();

            if (optim.d < distTo[optim.v]) {
                distTo[optim.v] = optim.d;
                parentOf[optim.v] = optim.from;
                for (Edge e : G.get(optim.v)) {
                    if (optim.from != e.v) { // prevent go back
                        pq.add(new SDto(e.v, distTo[optim.v] + e.c, optim.v));
                    }
                }

            }
        }

    }

    private static class SDto implements Comparable<SDto> { // Shortest distance to vertex
        int v, d, from;

        SDto(int v, int d, int from) {
            this.v = v;
            this.d = d;
            this.from = from;
        }

        @Override
        public int compareTo(SDto that) {
            if(this.d > that.d) return 1;
            else if(this.d < that.d) return -1;
            return 0;
        }


    }

    public static void main(String[] args) {
        Scanner in = new Scanner(System.in);

        int n = in.nextInt();

        ArrayList<ArrayList<Edge>> G = new ArrayList<>(n);
        for (int i = 0; i < n; i++) {
            G.add(new ArrayList<>());
        }

        for (int i = 0; i < n; i++) {
            int u = in.nextInt();
            int k = in.nextInt();
            for (int j = 0; j < k; j++) {
                int v = in.nextInt(), c = in.nextInt();
                G.get(i).add(new Edge(v, c));
                G.get(v).add(new Edge(i, c));
            }
        }

        Main dijkstra = new Main(G);

        for (int i = 0; i < G.size(); i++) {
            System.out.printf("%d %d\n", i, dijkstra.distTo[i]);
        }
    }
}

class Edge {
    int v, c;

    Edge(int v, int c) {
        this.v = v;
        this.c = c;
    }

    @Override
    public String toString() {
        return String.format("(v=%d, c=%d)", v, c);
    }
}