Go: package main

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

const (
	white int = iota
	gray
	black
)

type node struct {
	id     int
	parent int
	edge   []int
	weight []int
	color  int
}

type graph struct {
	nodes    []node
	distance []int
}

var infty = 1 << 32
var null = -1

func constructgraph() *graph {
	sc := bufio.NewScanner(os.Stdin)
	sc.Split(bufio.ScanWords)
	n := nextInt(sc)

	g := &graph{make([]node, n), make([]int, n)}

	for i := 0; i < n; i++ {
		id := nextInt(sc)
		edges := nextInt(sc)
		n := node{}
		n.id = id
		n.edge = make([]int, edges)
		n.weight = make([]int, edges)
		n.color = white
		for j := 0; j < edges; j++ {
			to := nextInt(sc)
			w := nextInt(sc)
			n.edge[j] = to
			n.weight[j] = w
		}
		g.nodes[id] = n
	}
	return g
}

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

func (g *graph) preparedijkstra(s int) {
	for i := 0; i < len(g.nodes); i++ {
		g.nodes[i].color = white
		g.nodes[i].parent = null
		g.distance[i] = infty
	}
	g.distance[s] = 0
}

func (g *graph) dijkstra(s int) []int {
	g.preparedijkstra(s)

	for {
		var u int
		mincost := infty
		for i, d := range g.distance {
			if g.nodes[i].color != black && mincost > d {
				mincost = d
				u = i
			}
		}

		if mincost == infty {
			break
		}

		g.nodes[u].color = black

		for i, e := range g.nodes[u].edge {
			if g.nodes[e].color != black {
				if g.distance[e] > g.distance[u]+g.nodes[u].weight[i] {
					g.distance[e] = g.distance[u] + g.nodes[u].weight[i]
					g.nodes[e].parent = u
					g.nodes[e].color = gray
				}
			}
		}
	}
	return g.distance
}

func printShortestPath(d []int) {
	for i, v := range d {
		fmt.Printf("%d %d\n", i, v)
	}
}

func main() {
	g := constructgraph()
	d := g.dijkstra(0)
	printShortestPath(d)
}

C++: #include <cstdio>
#include <cstring>
#include <cstdlib>
#include <cmath>
#include <iostream>
#include <string>
#include <algorithm>
#include <vector>
#include <map>
#include <queue>
#include <utility>
using namespace std;
//_____
#define pb push_back
#define fi first
#define se second
#define mkp make_pair
#define ALL(x) x.begin(),x.end()
#define rep(i,n) for(int i=0; i<(n); ++i)
#define reps(i,f,n) for(int i=(f); i<=(n); ++i)
#define err(...) fprintf(stderr, __VA_ARGS__)
#define show(x) cerr << #x << ':' << x << endl
#define outl(x) cout << (x) << '\n'
#define FAST() cin.tie(0), ios::sync_with_stdio(false)
typedef long long ll;
typedef pair<int,int> pii;
template<class A, class B>inline bool chmax(A &a, B b){return b>a ? a=b,1 : 0;}
template<class A, class B>inline bool chmin(A &a, B b){return b<a ? a=b,1 : 0;}
inline bool inside(int y, int x, int H, int W){return(y>=0 && x>=0 && y<H && x<W);}
const int dx[] = {1, 0, -1, 0,  1, 1, -1, -1};
const int dy[] = {0, 1, 0, -1,  -1, 1, 1, -1};
#define INF 0x3f3f3f3f
#define LEN 1000011
#define NIL -1
//_______

int N;
vector <pii> G[101];
int mcos[101];

void dijkstra(int s)
{
   priority_queue < pii, vector<pii>, greater<pii> > pq;
   pq.push( mkp(0, s) );
   memset( mcos, INF, sizeof(mcos) );
   mcos[s] = 0;

   while( !pq.empty() ){
      const pii tmp = pq.top(); pq.pop();
      if( mcos[tmp.se] < tmp.fi )continue;

      for( const auto& v : G[tmp.se] ){
         const int nc = v.fi + tmp.fi;
         if( chmin( mcos[v.se], nc )) pq.push( mkp(nc, v.se) );
      }
   }
   return ;
}

signed main()
{
   FAST();
   cin >> N;
   rep(i, N){
      int u, k, to, c;
      cin >> u >> k;
      while(k--){
         cin >> to >> c;
         G[i].pb( mkp(c,to) );
      }
   }
   dijkstra(0);
   rep(i, N){
      cout << i << ' ' << mcos[i] << '\n';
   }
}

C++: #include<cstdlib>
#include<cstdio>
#include<algorithm>
#include<vector>
#include<queue>
using namespace std;
const int MAXN = (int)1e2 + 10;
const int INF = (int) 0x3f3f3f3f;

vector<int> g[MAXN],val[MAXN];
int n;
int d[MAXN],vis[MAXN];

void Dijkstra(int s){
    for(int i=1;i<=n;i++) d[i]=INF;
    d[s]=0;
    vis[s]=1;
    for(int i=0;i<g[0].size();i++){
        int v=g[0][i];
        if(!vis[v]) d[v]=min(d[v],d[0]+val[0][i]);
    }
    int cnt=1;
    while(cnt<=n){
        int id=-1;
        for(int i=1;i<=n;i++)if(!vis[i]){
            if(id==-1||d[id]>d[i]) id=i;
        }
        vis[id]=1;
        cnt++;
        for(int i=0;i<g[id].size();i++){
            int v=g[id][i];
            if(!vis[v]) d[v]=min(d[v],d[id]+val[id][i]);
        }
    }
}

void work(){
    scanf("%d",&n);
    for(int i=0;i<n;i++){
        int u,k; scanf("%d%d",&u,&k);
        while(k--){
            int v,c; scanf("%d%d",&v,&c);
            g[u].push_back(v);
            val[u].push_back(c);
        }
    }
    Dijkstra(0);
    for(int i=0;i<n;i++) printf("%d %d\n",i,d[i]);
}

int main(){
    work();
    return 0;
}

/*
5
0 3 2 3 3 1 1 2
1 2 0 2 3 4
2 3 0 3 3 1 4 1
3 4 2 1 0 1 1 4 4 3
4 2 2 1 3 3
*/

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, N[MAX][MAX];

int prim(){
  int u,minv;
  int d[MAX],p[MAX],color[MAX];

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

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

int main(){
  cin >>n;

  for(int i=0;i<n;i++){
    for(int j=0;j<n;j++){
      int e; cin >>e;
      M[i][j] =(e==-1) ? INFTY : e;
    }
  }

  cout << prim() << endl;

  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 dik(){
int min;
int d[MAX],color[MAX];

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

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

dik();

return 0;
}

C++: #include <iostream>
#include <vector>
#include <queue>

using namespace std;

struct adja {
    int v;
    int c;
};

int n;
vector<adja> g[100];
int d[100];

void search() {
    fill_n(d, n, 1 << 20);
    queue<int> q;
    q.push(0);
    d[0] = 0;
    while (!q.empty()) {
        int u = q.front();
        q.pop();
        for (int i = 0, s = g[u].size(); i < s; ++i) {
            if (d[g[u][i].v] > d[u] + g[u][i].c) {
                d[g[u][i].v] = d[u] + g[u][i].c;
                q.push(g[u][i].v);
            }
        }
    }
}

int main() {
    int u, k, v, c;
    cin >> n;
    for (int i = 0; i < n; ++i) {
        cin >> u >> k;
        g[u].resize(k);
        for (int j = 0; j < k; ++j) {
            cin >> g[u][j].v >> g[u][j].c;
        }
    }
    search();
    for (int i = 0; i < n; ++i) {
        cout << i << " " << d[i] << endl;
    }

    return 0;
}