Go: package main

import (
	"bufio"
	"container/heap"
	"fmt"
	"os"
	"strconv"
)

const NIL = -1

type Node struct {
	id     int
	weight int
}

func init() {
	sc.Split(bufio.ScanWords)
}

type NodeHeap []Node

func (h NodeHeap) Len() int           { return len(h) }
func (h NodeHeap) Less(i, j int) bool { return h[i].weight < h[j].weight }
func (h NodeHeap) Swap(i, j int)      { h[i], h[j] = h[j], h[i] }

func (h *NodeHeap) Push(x interface{}) {
	*h = append(*h, x.(Node))
}

func (h *NodeHeap) Pop() interface{} {
	old := *h
	n := len(old)
	x := old[n-1]
	*h = old[0 : n-1]
	return x
}

var sc = bufio.NewScanner(os.Stdin)

func scanInt() int {
	num, _ := strconv.Atoi(scanString())
	return num
}

func scanString() string {
	sc.Scan()
	return sc.Text()
}

func init() {
	sc.Split(bufio.ScanWords)
}

func main() {
	n := scanInt()

	route := make([][]Node, n)
	weight := make([]int, n)
	for i := 0; i < n; i++ {
		weight[i] = NIL
	}

	for i := 0; i < n; i++ {
		u := scanInt()
		k := scanInt()
		route[i] = make([]Node, k)
		for j := 0; j < k; j++ {
			route[u][j] = Node{id: scanInt(), weight: scanInt()}
		}
	}

	start := Node{id: 0, weight: 0}
	h := &NodeHeap{start}
	heap.Init(h)

	for h.Len() > 0 {
		node := heap.Pop(h).(Node)
		if weight[node.id] != NIL {
			continue
		}
		weight[node.id] = node.weight

		for _, nextNode := range route[node.id] {
			if weight[nextNode.id] != NIL {
				continue
			}
			nextNode.weight += node.weight
			heap.Push(h, nextNode)
		}
	}

	for i, w := range weight {
		fmt.Println(i, w)
	}
}

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

int n;
vector<pair<int, int> > adj[MAX]; // 重み付き有向グラフの隣接リスト表現

void dijkstra() {
    priority_queue<pair<int, int> > PQ;
    int color[MAX];
    int d[MAX];
    for (int i=0; i<n; i++) {
        d[i] = INFTY;
        color[i] = WHITE;
    }
    
    d[0] = 0;
    PQ.push(make_pair(0, 0));
    color[0] = GRAY;
    
    while ( !PQ.empty() ) {
        pair<int, int> f = PQ.top(); PQ.pop();
        int u = f.second;
        
        color[u] = BLACK;
        
        // 最小値を取り出し、それが最短でなければ無視
        if (d[u] < f.first * (-1)) continue;
        
        for (int j=0; j<adj[u].size(); j++) {
            int v = adj[u][j].first;
            if (color[v] == BLACK) continue;
            if (d[v] > d[u] + adj[u][j].second) {
                d[v] =  d[u] + adj[u][j].second
                // priority_queueはデフォルトで大きい値を優先するため-1をかける
                PQ.push(make_pair(d[v]*(-1), v));
                color[v] = GRAY;
            }
        }
    }
    
    for (int i=0; i<n; i++) {
        printf("%d %d\n", i, d[i]);
    }
}

int main() {
    int k, u, v, c;
    
    scanf("%d", &n);
    for (int i=0; i<n; i++) {
        scanf("%d %d", &u, &k);
        for (int j=0; j<k; j++) {
            scanf("%d %d", &v, &c);
            adj[u].push_back(make_pair(v, c));
        }
    }
    
    dijkstra();
    
    return 0;
}

C++: #include <bits/stdc++.h>

using namespace std;

#define Vi vector<int>
#define FOR(i,s,e) for (int i=s; i<e; i++)
#define ITER(v) v.begin(), v.end()

constexpr int N_MAX = 10000;
constexpr int INF   = 1<<30;

using IPAIR = pair<int, int>;

vector<IPAIR> weight[N_MAX];
int dis[N_MAX];

void set_shortest_distance(const int n) {
    FOR(i,0,n) {
        dis[i] = INF;
    }

    bool ismember[n] = { false };

    priority_queue<IPAIR, vector<IPAIR>, greater<IPAIR>> pq;
    pq.push(make_pair(0, 0));

    while (!pq.empty()) {
        IPAIR top = pq.top(); pq.pop();
        const int top_i = top.second;
        if (ismember[top_i]) { continue; }
        ismember[top_i] = true;
        const int top_d = top.first;
        dis[top_i] = top_d;
        for (const IPAIR& next : weight[top_i]) {
            const int next_i = next.second;
            if (ismember[next_i]) { continue; }
            const int next_w = next.first;
            const int d = top_d + next_w;
            pq.push(make_pair(d, next_i));
        }
    }
}

int main() {
    cin.tie(0);
    ios::sync_with_stdio(false);

    int n;
    cin >> n;

    int u, k, v, c;
    FOR(i,0,n) {
        cin >> u >> k;
        FOR(j,0,k) {
            cin >> v >> c;
            weight[u].push_back(make_pair(c,v));
        }
    }

    set_shortest_distance(n);

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

    return 0;
}

C++: #include<iostream>
#include<vector>
#include<algorithm>
#include<cstdio>
#include<cstdlib>
#include<string>
#include<sstream>
#include<cmath>
#include<numeric>
#include<map>
#include<stack>
#include<queue>
using namespace std;
int inf = 1000000000;

class node{
public:
  int to;
  int from;
  int cost;
};

int main(void) {

  int n; scanf("%d", &n);
  vector< vector<node> > v(n);
  for(int i=0; i<n; i++){
    int u, k;
    scanf("%d %d", &u, &k);
    for(int j=0; j<k; j++){
      int vv, c;
      scanf("%d %d", &vv, &c);
      node t;
      t.from = u;
      t.to = vv;
      t.cost = c;
      v[u].push_back(t);
    }
  }

  vector<int> dist(n, inf);
  vector<bool> vis(n, false);

  priority_queue< pair<int, int> > pq;
  pq.push(make_pair(0, 0));
  dist[0] = 0;
  vis[0] = true;
  while( !pq.empty() ){
    pair<int, int> pos = pq.top();
    pq.pop();
    int p = pos.second;
    vis[pos.second] = true;
    for(int i=0; i<v[p].size(); i++){
      if( p != v[p][i].from ) continue;
      if( dist[v[p][i].to] < dist[v[p][i].from] + v[p][i].cost ) continue;

      dist[v[p][i].to] = min(dist[v[p][i].to], dist[v[p][i].from] + v[p][i].cost);
      pq.push(make_pair(dist[v[p][i].to], v[p][i].to));
    }

  }

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

  return 0;
}

// EOF

C++: #include <map>
#include <vector>
#include <cstdio>
using namespace std;
int main(){
	int n=0,N,i,j,k,c;
	scanf("%d",&N);
	vector<map<int,int> >dist(N);
	vector<bool>used(N);
	vector<int>cost(N);
	for(;n<N;n++){
		cost[n]=9999999;
		for(scanf("%d%d",&i,&k);k--;dist[j][i]=c)scanf("%d%d",&j,&c); //i->j cost c
	}
	for(cost[0]=0;;){ //dijkstra
		int m=9999999;
		for(i=0;i<N;i++)if(!used[i]&&m>cost[i])m=cost[i];
		if(m==9999999)break;
		for(j=0;j<n;j++)if(m==cost[j]){
			map<int,int>::iterator it=dist[j].begin();
			for(used[j]=1;it!=dist[j].end();it++)if(cost[it->first]>it->second+cost[j])cost[it->first]=it->second+cost[j];
		}
	}
	for(i=0;i<n;i++)printf("%d %d\n",i,cost[i]);
}

C++: #include <bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef pair<int, int> P;
#define MAX 10000000000

int main(void){
  ios::sync_with_stdio(false);
  cin.tie(0);

  int n; cin >> n;

  vector< vector< P > > f(n);
  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;
      f[u].push_back(make_pair(v, c));
    }
  }

  priority_queue< P, vector<P>, greater<P> > que;
  vector<ll> d(n, MAX);
  d[0] = 0;
  que.push(make_pair(0, 0));

  while(!que.empty()){
    P q = que.top(); que.pop();
    if(q.first > d[q.second]) continue;
    
    for(int i = 0; i < f[q.second].size(); i++){
      if(d[ f[q.second][i].first ] > d[q.second] + f[q.second][i].second){
        d[ f[q.second][i].first ] = d[q.second] + f[q.second][i].second;
        que.push(make_pair(d[ f[q.second][i].first ], f[q.second][i].first));
      }
    }
  }

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

  return 0;
}