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>
#include<vector>

using namespace std;

#define WHITE 0
#define BLACK 2
#define GRAY 1
#define MAX 100
#define INFITY 1<<21

int n;
vector<pair<int,int> > adj[MAX];

void dijkstra()
{
	priority_queue<pair<int,int> > PQ;
	int d[MAX],color[MAX],p[MAX];

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

	d[0]=0;
	color[0]=GRAY;
	PQ.push(make_pair(0,0));

	while(!PQ.empty()){

		// 把距离最小的顶点加入单源最短路径树
		pair<int,int> f=PQ.top();
		PQ.pop();
		int u=f.second;
		color[u]=BLACK;

		// 更新距离
		for (int i = 0; i < adj[u].size(); ++i)
		{
			int v=adj[u][i].first;
			if (color[v]==BLACK)
			{
				continue;
			}
			if (d[v]>d[u]+adj[u][i].second)
			{
				d[v]=d[u]+adj[u][i].second;
				PQ.push(make_pair(d[v]*-1,v));
				color[v]=GRAY;
				p[v]=u;
			}
		}
	}

	for (int i = 0; i < n; ++i)
	{
		cout<<i<<" "<<(d[i]==INFITY?-1:d[i])<<endl;
	}

}

int main(int argc, char const *argv[])
{
	int u,k,v,c;
	cin>>n;
	for (int i = 0; i < n; ++i)
	{

		cin>>u>>k;
		for (int j = 0; j < k; ++j)
		{
			cin>>v>>c;
			adj[u].push_back(make_pair(v,c));
		}
	}
	dijkstra();
	return 0;
}

C++: #include<iostream>
#include<algorithm>
#include<queue>
using namespace std;
static const int INF = 1<<20;
int n;
vector<pair<int, int> > adj[10000];
void dijkstra(){
	priority_queue<pair <int, int> > PQ;
	int color[10000];
	int d[10000];
	for(int i=0; i<n; i++){
		d[i]=INF;
		color[i]=0;
	}
	d[0]=0;
	PQ.push(make_pair(0, 0));
	color[0]=1;
	while(!PQ.empty()){
		pair<int, int> f=PQ.top();
		PQ.pop();
		int u=f.second;
		color[u]=2;
		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]==2)
				continue;
			if(d[v]>d[u]+adj[u][j].second){
				d[v]=d[u]+adj[u][j].second;
				PQ.push(make_pair(d[v]*(-1), v));
				color[v]=1;
			}
		}
	}
	for(int i=0; i<n; i++)
		cout<<i<<" "<<(d[i]==INF ? -1 : d[i])<<endl;
}
int main(){
	int k,u,v,c;
	cin>>n;
	for(int i=0; i<n; i++){
		cin>>u>>k;
		for(int j=0; j<k; j++){
			cin>>v>>c;
			adj[u].push_back(make_pair(v, c));
		}
	}
	dijkstra();
	return 0;
}

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

struct Edge {int to, cost;};

typedef vector<Edge> Edges;
typedef vector<Edges> Graph;

int mind(vector<int> &a,vector<int> &b){
	int n=a.size();
	int min=INT_MAX;
	int ind=0;
	for (int i=0;i<n;i++){
		if((min>a[i])&&(b[i]==0)){
			min=a[i];
			ind=i;
		}
	}
	if(min==INT_MAX){
		return -1;
	}else{
		return ind;
	}
}

int min(vector<int> &a){
	int n=a.size();
	int min=a[0];
	int ind=0;
	for (int i=0;i<n;i++){
		if(min>a[i]){
			min=a[i];
			ind=i;
		}
	}
	return min;
}

void dijkstra(Graph &G,vector<int> &d,int n,int s){
	fill(d.begin(),d.end(),INT_MAX);
	vector<int> c(n,0);
	int t;
	
	d[s]=0;
	
	while((t=mind(d,c))!=-1){
		c[t]=1;
		for(int i=0;i<G[t].size();i++){
			Edge e=G[t][i];
			if(d[e.to] > d[t]+e.cost){
				d[e.to] = d[t]+e.cost;
			}
		}
	}
}

int main(){
	int n,i,j,k;
	vector<int> d(n);
	Edge e;
	
	cin >> n;
	
	Graph G(n);
	
	for (i=0;i<n;i++){
		cin >> k >> k;
		for (j=0;j<k;j++){
			cin >> e.to >> e.cost;
			G[i].push_back(e);
		}
	}
	
	dijkstra(G,d,n,0);
	
	for (i=0;i<n;i++){
		cout << i << " " << d[i] << endl;
	}
	
	return 0;
}

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

typedef struct{
  int A[10010];
  int ans;
}node;
node T[10010];
int head=0;
int tail=1;
int n;

void function(int num){
  int *Q=new int[1000000];
  Q[0]=0;
  while(true){
    if(head==tail)break;
    num=Q[head++];
        if(head==999999)head=1;
    for(int i=0;i<n;i++){
      if(T[num].A[i]!=-1){
	if(T[i].ans>T[num].ans+T[num].A[i]){
	  T[i].ans=T[num].ans+T[num].A[i];
	  Q[tail++]=i;
	  	  if(tail==999999)tail=1;
	}
      }
    }
  }
  delete [] Q;
}

int main(){
  int num,son,z,w;
  cin>>n;
  for(int i=0;i<n;i++){
    for(int j=0;j<n;j++){
      T[i].A[j]=-1;
    }
  }


  for(int i=0;i<n;i++){
    cin>>num>>son;
    T[num].ans=INT_MAX;
    for(int j=0;j<son;j++){
      cin>>z>>w;
      T[num].A[z]=w;
      }
  }

  T[0].ans=0;
  function(0);
 
  for(int i=0;i<n;i++){
      cout<<i<<" "<<T[i].ans<<endl;
  }
  return 0;
}

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

using namespace std;

const int MAX_N = 10005;
const int INFTY = 1001001001;
typedef pair<int, int> P;

vector< vector< P > > adj(MAX_N);
vector<int> state(MAX_N, 0);
vector<int> dist(MAX_N, INFTY);
int n;

void djkstra(int node)
{
    priority_queue< P, vector<P>, greater<P> > Q;
    Q.push(P(0, node));
    dist[node] = 0;
    int v;

    while(!Q.empty()){
        P p = Q.top();
        Q.pop();
        node = p.second;

        state[node] = 1;

        //if(dist[node] < p.first) continue;

        for(int j=0;j<adj[node].size();++j){
            // node → jのコスト
            v = adj[node][j].first;
            if(state[v]) continue;
            if(dist[v] > dist[node] + adj[node][j].second){
                dist[v] = dist[node] + adj[node][j].second;
                Q.push(P(dist[v], v));
            }
        }
    }

    for(int i=0;i<n;++i){
        dist[i] = dist[i] == INFTY ? -1 : dist[i];
    }
}

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

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