Go: package main

import (
	"strconv"
	"fmt"
	"bufio"
	"os"
)
const INF = 1 << 21
var scanner = bufio.NewScanner(os.Stdin)

func nextInt() int {
	scanner.Scan()
	i, e := strconv.Atoi(scanner.Text())
	if e != nil {
		panic(e)
	}
	return i
}


func main() {
	scanner.Split(bufio.ScanWords)
	n := nextInt()
	adj := make([][]int, n)
	for i := range adj {
		adj[i] = make([]int, n)
	}

	for i := 0;i < n; i++ {
		u := nextInt()
		k := nextInt()
		for j := 0; j < k; j++ {
			v := nextInt()
			c := nextInt()
			adj[u][v] = c
		}
	}

	// for i := range adj {
	// 	fmt.Println(adj[i])
	// }

	dist := make([]int, n)
	prev := make([]int, n)
	visited := make([]bool, n)
	dijkstra := func(start int, size int) {
		for i := 0; i < size; i++ {
			dist[i] = INF
			prev[i] = -1
			visited[i] = false
		}
		dist[start] = 0
		for {
			u := -1
			tmp_min := INF
			for i := 0; i < size; i++ {
				if visited[i] == false && dist[i] < tmp_min {
					tmp_min = dist[i]
					u = i
				}
			}
			if u == -1 {
				break
			}
			visited[u] = true
			for i := 0; i < size; i++ {
				if adj[u][i] > 0 {
					w := adj[u][i]
					newlen := dist[u] + w
					if newlen < dist[i] {
						dist[i] = newlen
						prev[i] = u
					}
				}
			}
		}
	}
	dijkstra(0, n)
	for i, cost := range dist {
		fmt.Printf("%d %d\n", i, cost)
	}
}

C++: /**
 *      purpose : 
 *      author  : kyomukyomupurin
 *      created : 
**/

// input/output
#include <fstream>
#include <iostream>
#include <sstream>
// container class
#include <array>
#include <deque>
#include <map>
#include <queue>
#include <set>
#include <stack>
#include <string>
#include <tuple>
#include <unordered_map>
#include <unordered_set>
#include <vector>
// math, algorithm
#include <algorithm>
#include <cmath>
#include <complex>
#include <numeric>
// etc
#include <bitset>
#include <cassert>
#include <cctype>
#include <cstring>
#include <chrono>
#include <functional>
#include <iomanip>
#include <random>
#include <utility>
// using-directive
using namespace std;
// alias template
using int64 = long long;
using uint64 = unsigned long long;
using vi = std::vector<int>;
using vl = std::vector<int64>;
using pii = std::pair<int, int>;
using pii = std::pair<int, int>;
using pll = std::pair<int64, int64>;
// text macro replacement
#define rep(i, n) for (int i = 0; i < (int)(n); ++i)
#define all(_) (_).begin(), (_).end()
#define rall(_) (_).rbegin(), (_).rend()
#define print(_) std::cout << (_) << '\n'
#define debug(_) std::cerr << #_ << ": " << (_) << '\n'
#define dbg(vec) for (size_t _ = 0; _ < vec.size(); ++_){std::cerr << #vec << "[" << _ << "] : " << vec[_] << '\n';}
// variadic template
template<typename T> inline void chmin(T &a, T b) {if (a > b) a = b; return;}
template<typename T> inline void chmax(T &a, T b) {if (a < b) a = b; return;}
// constant
const int INF = (1<<30) - 1;  // 1.073741823e9
const int64 INF64 = (1LL<<62) - 1;  // 4.611686018427387903e18
const int MOD = 1000000007;

const int MAX_V = 101010;
//const int64 INF64 = (1LL<<62) - 1;

struct edge {
  int64 to, cost;
};

int n;
std::vector<edge> G[MAX_V];
int64 dis[MAX_V];

void dijkstra(int s){
  std::priority_queue<std::pair<int64, int64>,
                      std::vector<std::pair<int64, int64>>,
                      std::greater<std::pair<int64, int64>>> pq;
  std::fill(dis, dis + n, INF64);
  dis[s] = 0;
  pq.push(std::pair<int64, int64>(0, s));

  while (!pq.empty()){
    std::pair<int64, int64> p = pq.top(); pq.pop();
    int v = p.second;
    if (dis[v] < p.first) continue;
    for (size_t i = 0; i < G[v].size(); ++i){
      edge e = G[v][i];
      if (dis[e.to] > dis[v] + e.cost){
        dis[e.to] = dis[v] + e.cost;
        pq.emplace(std::pair<int64, int64>(dis[e.to], e.to));
      }
    }
  }
}

int main(){
  std::ios_base::sync_with_stdio(false);
  std::cin.tie(nullptr);

  cin >> n;
  for (int i = 0; i < n; ++i) {
    int u, k; cin >> u >> k;
    for (int j = 0; j < k; ++j) {
      int64 v, c; cin >> v >> c;
      G[u].push_back({v, c});
    }
  }

  dijkstra(0);

  for (int i = 0; i < n; ++i) {
    cout << i << " " << dis[i] << '\n';
    //if (i != n - 1) cout << '\n';
  }

  return 0;
}

C++: #include<iostream>
using namespace std;
static const int MAX = 100;
static const int INFTY = (1 << 21);
static const int WHITE = 0;
static const int GRAY = 1;
static const int BLACK = 2;

int n, M[MAX][MAX];


void dijkstra(){
  int minv;
  int d[MAX], color[MAX];

  for(int i = 0 ; i < n ; i++){
    d[i] = INFTY;
    color[i] = WHITE;
  }

  d[0] = 0;
  color[0] = INFTY;
  while(1){
    minv = INFTY;
    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] != INFTY){
        if(d[v] > d[u] + M[u][v]){
          d[v] = d[u] + M[u][v];
          color[v] = GRAY;
        }
      }
    }
  }
  for(int i = 0 ; i < n ; i++){
    cout << i << " " << (d[i] == INFTY ? -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] = INFTY;
    }
  }

  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++: #define _CRT_SECURE_NO_WARNINGS

#include<fstream>
#include<iostream>
#include<string>
#include<iomanip>
#include<list>
#include<math.h>
#include<stack>
#include<queue>
#include<vector>
#include<algorithm>
#include<utility>

using namespace std;

int main(){
	int a[100][100];
	int n;
	cin >> n;

	for (int i = 0; i < n; i++) {
		for (int j = 0; j < n; j++) {
			a[i][j] = 10000000;
		}
		a[i][i] = 0;
	}

	for (int i = 0; i < n; i++) {
		int u, k;
		cin >> u >> k;
		a[i][i] = 0;
		for (int j = 0; j < k; j++) {
			int c, v;
			cin >> v >> c;
			a[u][v] = c;
		}
	}
	for (int k = 0; k < n; k++) {
		for (int i = 0; i < n; i++) {
			for (int j = 0; j < n; j++) {
				a[i][j] = min(a[i][j], a[i][k] + a[k][j]);
			}
		}
	}
	for (int i = 0; i < n; i++) {
		cout << i << " " << a[0][i] << endl;
	}
	return 0;
}

C++: #include<bits/stdc++.h>
using namespace std;
#define INF 1<<30
struct edge{int to,cost;};
vector<edge> G[101];
int d[101];
bool visited[101];

void dijkstra(int n){
  fill(d+1,d+101,INF);
  memset(visited,false,sizeof(visited));
  for(int i=0;i<n;++i){
    int id=-1;
    for(int j=0;j<n;++j){
      if(!visited[j])
        if(id==-1||d[id]>d[j]) id=j;
    }
    visited[id]=true;
    for(int j=0;j<G[id].size();++j){
      edge e=G[id][j];
      d[e.to]=min(d[e.to],d[id]+e.cost);
    }
  }
}
int main(){
  int n; cin>>n;
  for(int i=0;i<n;++i){
    int u,k; cin>>u>>k;
    for(int j=0;j<k;++j){
      int c,v; cin>>c>>v;
      edge e; e.to=c, e.cost=v;
      G[u].push_back(e);
    }
  }
  dijkstra(n);
  for(int i=0;i<n;++i) cout<<i<<" "<<d[i]<<endl;
  return 0;
}