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<queue>
#include<vector>
using namespace std;

static const int MAX = 10000;
static const int INF = (1<<21);
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(){
    int color[MAX], d[MAX];

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

    d[0] = 0;

    // pair<vに到達するまでのスコア、v>
    priority_queue<pair<int,int>> pq;
    pq.push({0,0});

    while(!pq.empty()){
        pair<int,int> p = pq.top(); pq.pop();
        int u = p.second;
        
        color[u] = BLACK;
        if(d[u] < p.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][v].second){
                d[v] = d[u] + adj[u][v].second;
                pq.push((-1)*d[v], v);
                color[v] = GRAY;
            }
        }
    }

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

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({v,c});
       }
   }

   dijkstra();

   return 0;
}

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

class blanch{
	public:
		bool visited;
		int distance;
		int from;
		int to;
};
typedef vector <blanch> vb;
typedef vector <vb> vvb;

int make_graph(vvb &graph, vb &nodes){

	int n=nodes.size();
	for (int i=0; i<n; i++){
		nodes[i].visited = false;
		nodes[i].distance = INT_MAX;
	}

	for (int i=0; i<n; i++){
		int i2, n2;
		cin>>i2;
		cin>>n2;

		blanch tmp;
		tmp.visited = false;
		tmp.from = i2;

		for (int j=0; j<n2; j++){
			cin>>tmp.to;
			cin>>tmp.distance;
			graph[i2].push_back(tmp);
		}
	}
	return 0;
}

int Shortest_Path(vvb &graph, vb &nodes){

	int p1=0;
	nodes[p1].distance = 0;

	int p2;
	while (p1 != -1){
		nodes[p1].visited=true;
		for (int i = 0; i < (int)graph[p1].size(); i++){
			blanch tmp = graph[p1][i];
			p2=tmp.to;
			if (!nodes[p2].visited){
				int tmp2 = tmp.distance + nodes[p1].distance;
				if (tmp2 < nodes[p2].distance){
					tmp.distance = tmp2;
					nodes[p2] = tmp;
				}
			}
		}

		p1 = -1;
		int tmp = INT_MAX;
		for (int i=0; i<(int)graph.size(); i++){
			if (!nodes[i].visited && nodes[i].distance<tmp){
				p1 = i;
				tmp = nodes[i].distance;
			}
		}
	}
	return 0;
}

int resultout(vb &nodes){
	for (int i=0; i<(int)nodes.size(); i++){
		cout<<i<<" "<<nodes[i].distance<<endl;
	}
	return 0;
}

int main(void){

	int n;
	cin>>n;
	vvb G(n, vb());
	vb nodes(n);

	make_graph(G, nodes);

	Shortest_Path(G, nodes);

	resultout(nodes);
	G.clear();
	nodes.clear();

	return 0;
}

C++: #include<iostream>
#include<cstdio>
#include<string>
#include<algorithm>
#include<cstring>
#include<vector>
#include<cmath>
#include<queue>
#include<stack>
using namespace std;
#define INT(x) int x; scanf("%d",&x)
#define INPUT(x) scanf("%d",&x)
#define REP1(x,n) for(int x = 0; x < n; x++)
#define REP2(x,s,e) for(int x = s; x <= e; x++)
#define RREP1(x,n) for(int x = n-1; x >= 0; x--)
#define RREP2(x,s,e) for(int x = s; x >= e; x--)
#define BR printf("\n")
#define INF 2000000000
#define INF_LL 9223372036854775806

typedef long long ll;

int G;

ll length[10000];

class edge{
public:
    int fromid;
    int toid;
    int m;
    int len;
    
    edge(int from){
        len = 0;
        fromid = from;
        INPUT(toid);
        INPUT(m);
    }
    
    bool operator < (const edge &e) const {
        return len < e.len;
    }
};

//??§?????????????????????????????????????????§??????????????\?????????
priority_queue<edge> PQ;
vector<vector<edge> > eList;

void dijkstra(int i, ll len){
    if(length[i] != INF_LL) return;
    
    //1.??????????????¢????¢????
    PQ.pop();
    length[i] = len;
    
    //2.?¨??????????????£????????´?
    REP1(k,eList[i].size()){
        if(length[i] != INF_LL){
            eList[i][k].len = -length[i] - eList[i][k].m;
            PQ.push(eList[i][k]);
        }
    }
    
    //3.?¬?????¨??????????????¢?????????????
    while (PQ.size() != 0 && length[PQ.top().toid] != INF_LL) {
        PQ.pop();
    }
    
    //4.?????£????????????
    if (PQ.size() != 0) {
        dijkstra(PQ.top().toid, -PQ.top().len);
    }
}

int main(){
    INPUT(G);
    REP1(i,G){
        vector<edge> list;
        eList.push_back(list);
        length[i] = INF_LL;
        INT(from);
        INT(k);
        REP1(j,k){
            edge e(from);
            eList[i].push_back(e);
        }
    }
    PQ.push(eList[0][0]);
    
    dijkstra(0,0);
    
    REP1(i,G){
        printf("%d %lld\n",i,length[i]);
    }
    
    return 0;
}

C++: #include <stdio.h>
#include <vector>

using namespace std;

struct Info{
	Info(int arg_weight,short arg_to){
		weight = arg_weight;
		to = arg_to;
	}
	int weight;
	short to;
};


int main(){
	int n,count=0,t,min,min_index,tmp,left_node,right_node,dist,t_to_i;
	scanf("%d",&n);
	vector<Info> V[n];

	int P[n],zero_dist[n];

	for(int i=0;i<n;i++){
		P[i]=0;
		zero_dist[i] = 10000001;
	}
	zero_dist[0] = 0;
	P[0]=1;

	for(int i=0;i<n;i++){
		scanf("%d %d",&left_node,&tmp);
		if(left_node == 0){
			for(int k=0;k<tmp;k++){
				scanf("%d %d",&right_node,&dist);
				zero_dist[right_node] = dist;
			}
		}else{
			for(int k=0;k<tmp;k++){
				scanf("%d %d",&right_node,&dist);
				V[left_node].push_back(Info(dist,right_node));
			}
		}
	}

	while(count<n-1){

		min=10000001;
		for(int i=1;i<n;i++){
			if(P[i]==0&&zero_dist[i]<min){
				min_index = i;
				min = zero_dist[i];
			}
		}
		t = min_index;
		P[t]=1;
		count++;

		for(int i=1;i<n;i++){
			t_to_i = 10000001;
			for(int k=0;k<V[t].size();k++){
				if(V[t][k].to == i){
					t_to_i = V[t][k].weight;
					break;
				}
			}
			if(zero_dist[i] > zero_dist[t]+t_to_i){
				zero_dist[i]=zero_dist[t]+t_to_i;
			}
		}
	}

	for(int i=0;i<n;i++){
		printf("%d %d\n",i,zero_dist[i]);
	}

    return 0;
}