Go: package main

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

var sc = bufio.NewScanner(os.Stdin)

const T = 10000000

var n int
var A [101][101]int

func nextInt() int {
	sc.Scan()
	i, _ := strconv.Atoi(sc.Text())
	return i
}
func Shortestsearch() {
	var Minimum int
	var d, color [100]int
	var u int

	for i := 0; i < n; i++ {
		d[i] = T
		color[i] = 0
	}

	d[0] = 0
	color[0] = 1

	for {
		Minimum = T
		u = -1
		for i := 0; i < n; i++ {
			if Minimum > d[i] && color[i] != 2 {
				u = i
				Minimum = d[i]
			}
		}
		if u == -1 {
			break
		}
		color[u] = 2
		for j := 0; j < n; j++ {
			if color[j] != 2 && A[u][j] != T {
				if d[j] > d[u]+A[u][j] {
					d[j] = d[u] + A[u][j]
					color[j] = 1
				}
			}
		}
	}
	for i := 0; i < n; i++ {
		fmt.Printf("%d %d\n", i, d[i])
	}
}
func main() {
	sc.Split(bufio.ScanWords)
	n = nextInt()

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

C++: #include <bits/stdc++.h>
using namespace std;


typedef pair<int, int> P;
#define int long long

const int INF = LONG_LONG_MAX;
struct edge {int to, cost;};

/*
[input]
const vector<vector<edge>> &graph : ??\?????°??????
int s : ?§????
int g : ??????
n*/
int dijkstra(const vector<vector<edge>> &graph, int s, int g ) {
  // ????????????????±?????????????????????????
  vector<int> d(graph.size(), INF);
  // ????§?????????????????????????0????????????
  d[s] = 0;
  // ??????????????????now
  set<P> now;
  // ????§?????????????now????????\
  now.insert(P(0, s));
  
  // now????????????????????§
  while(!now.empty()) {
    // ?????¨?????????????????????pos???????´?
    int pos = now.begin()->second;
    // ?????¨??????????????????????????????????±???????????????????????????????
    if (pos == g) {
      for(int i = 0; i <= g; i++) {
        cout << i << " " << d[i] << endl;
      }
      return INF;
    }
    // now????????¢?´¢?????????????¶????
    now.erase(now.begin());
    // ?????¨??????????????¨???????????¢?´¢
    for(auto ed: graph[pos]) {
      // ??\?¶??????????????????????????????????????????¨??????????????§????????????
      // ??¨??\?¶?????????§?????¨????????????????????????????????§???????????°
      if(d[ed.to] > d[pos] + ed.cost) {
        // now????????\?¶?????????????????±????????????????????????????
        now.erase(P(d[ed.to], ed.to));
        d[ed.to] = d[pos] + ed.cost;
        now.insert(P(d[ed.to], ed.to));
      }
    }
  }
  return INF;
}
  
signed main() {
  int num;
  cin >> num;
  vector<vector<edge>> graph(num, vector<edge>());
  int f, n, k, v, c;
  for(int i = 0; i < num; i++) {
    cin >> f >> k;
	if(k == 0) continue;
    for(int j = 0; j < k; j++) {
      cin >> v >> c;
      graph[f].push_back(edge{v, c});
      graph[v].push_back(edge{f, c});
    }
  }
  dijkstra(graph, 0, num - 1);
  return 0;
}

C++: #include <iostream>
#include <queue>
#include <vector>
using namespace std;

struct Node {
  int v, cost;
  bool operator>(const Node &n) const {
    return cost > n.cost;
  }
};

int main() {
  int n;
  cin >> n;

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

  vector<int> dists(n, -1);
  priority_queue<Node, vector<Node>, greater<Node>> q;
  q.push({0, 0});
  while (!q.empty()) {
    Node node = q.top();
    q.pop();

    if (dists[node.v] != -1) {
      continue;
    }
    dists[node.v] = node.cost;

    for (int i = 0; i < n; i++) {
      if (g[node.v][i] != -1) {
	q.push({i, node.cost + g[node.v][i]});
      }
    }
  }

  for (int i = 0; i < n; i++) {
    cout << i << ' ' << dists[i] << endl;
  }

  return 0;
}

C++: #include <iostream>
#include <algorithm>
#include <vector>
#include <set>
#include <cmath>
#include <deque>
#include <iterator>
#include <map>
#include <queue>
#include <string>
#include <tuple>
#include <utility>
using namespace std;

using ll=long long;
template<class T> using V = vector<T>;
template<class T, class U> using P = pair<T, U>;
using vll = V<ll>;
using vvll = V<vll>;
#define rep(i, k, n) for (ll i=k; i<(ll)n; ++i)
#define REP(i, n) rep(i, 0, n)
template<class T> inline bool chmax(T& a, T b) {if (a<b) {a=b; return true;} return false;}
template<class T> inline bool chmin(T& a, T b) {if (a>b) {a=b; return true;} return false;}

const ll MOD = 1000000007;
const ll HIGHINF = (ll)1e18;

int main() {
  ll n; cin >> n;
  vvll edges(n, vll(n, -1));
  REP(i, n) {
    ll u, k; cin >> u >> k;
    REP(j, k) {
      ll v, c; cin >> v >> c;
      edges.at(u).at(v) = c;
    }
  }
  vll d(n, HIGHINF);
  V<bool> visited(n, false);
  d.at(0) = 0;
  REP(i, n) {
    ll now = -1;
    ll mind = HIGHINF;
    REP(j, n) {
      if (!visited.at(j) && d.at(j) < mind) {
        now = j;
        mind = d.at(j);
      }
    }
    REP(j, n) {
      if (edges.at(now).at(j) != -1 && d.at(j) > d.at(now) + edges.at(now).at(j)) {
        d.at(j) = d.at(now) + edges.at(now).at(j);
      }
    }
    visited.at(now) = true;
  }
  REP(i, n) cout << i << ' ' << d.at(i) << endl;
  return 0;
}