Go: package main

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

//make priority queue
type Item struct {
	id       int
	priority int // this state is priority and distans from start
	index    int
}

type PriorityQueue []*Item

func (pq PriorityQueue) Len() int { return len(pq) }

// we want the ascending-priority-queue.
// So we use less than here.
func (pq PriorityQueue) Less(i, j int) bool {
	return pq[i].priority < pq[j].priority
}

func (pq PriorityQueue) Swap(i, j int) {
	pq[i], pq[j] = pq[j], pq[i]
	pq[i].index = j
	pq[j].index = i
}

func (pq *PriorityQueue) Push(x interface{}) {
	n := len(*pq)
	item := x.(*Item)
	item.index = n
	*pq = append(*pq, item)
}

func (pq *PriorityQueue) Pop() interface{} {
	old := *pq
	n := len(old)
	item := old[n-1]
	item.index = -1 //for safety
	*pq = old[0 : n-1]
	return item
}

func (pq *PriorityQueue) update(dist int, id int) {
	for _, i := range *pq {
		if i.id == id {
			if i.priority > dist {
				i.priority = dist
			}
		}
	}
}

// the main code
func nextInt(sc *bufio.Scanner) int {
	sc.Scan()
	n, _ := strconv.Atoi(sc.Text())
	return n
}

func dikstra(dist [][]int, n int) []int {
	// preparate priority queue
	inf := 1 << 30
	pq := make(PriorityQueue, n)
	shortests := make([]int, n)
	for i := 0; i < n; i++ {
		pq[i] = &Item{
			id:       i,
			priority: inf,
			index:    i,
		}

		shortests[i] = inf
	}
	pq[0].priority = 0
	shortests[0] = 0

	for pq.Len() > 0 {
		item := heap.Pop(&pq).(*Item)
		shortests[item.id] = item.priority
		for id, d := range dist[item.id] {
			if d != -1 {
				pq.update(item.priority+d, id)
			}
		}
		heap.Init(&pq)
	}
	return shortests
}

func main() {
	sc := bufio.NewScanner(os.Stdin)
	sc.Split(bufio.ScanWords)

	// init
	n := nextInt(sc)
	dist := make([][]int, n)
	for i := 0; i < n; i++ {
		dist[i] = make([]int, n)
		for j := 0; j < n; j++ {
			dist[i][j] = -1
		}
	}

	// std Input
	for i := 0; i < n; i++ {
		u := nextInt(sc)
		k := nextInt(sc)
		for j := 0; j < k; j++ {
			v, c := nextInt(sc), nextInt(sc)
			dist[u][v] = c
		}
	}

	shortests := dikstra(dist, n)
	for i, d := range shortests {
		fmt.Printf("%d %d\n", i, d)
	}
}

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

#define rep(i, a, b) for (int i = (a); i < (int)(b); i++)
#define rrep(i, a, b) for (int i = (a); i >= (int)(b); i--)
#define all(x) (x).begin(), (x).end()
using i32 = int32_t;
using i64 = int64_t;
using f32 = float;
using f64 = double;
using P   = pair<int, int>;

template <class T>
bool chmin(T& a, T b) {
    if (a > b) {
        a = b;
        return true;
    } else {
        return false;
    }
}
template <class T>
bool chmax(T& a, T b) {
    if (a < b) {
        a = b;
        return true;
    } else {
        return false;
    }
}

template <class T>
void dump_vec(const vector<T>& v) {
    auto len = v.size();
    rep(i, 0, len) {
        cout << v[i] << (i == (int)len - 1 ? "\n" : " ");
    }
}

struct FastIO {
    FastIO() {
        cin.tie(0);
        ios::sync_with_stdio(false);
        cout << fixed << setprecision(20);
    }
} FASTIO;

//---------------------------------------------------------------------------------------------------

struct Edge {
    int from, to;
    i64 cost;
    Edge() {}
    Edge(int t, i64 c) : from(-1), to(t), cost(c) {}
    Edge(int f, int t, i64 c) : from(f), to(t), cost(c) {}

    bool operator<(const Edge& r) const {
        return cost < r.cost;
    }
    bool operator>(const Edge& r) const {
        return cost > r.cost;
    }
};

using Vertex = vector<Edge>;
using Graph  = vector<Vertex>;

// 無向
void link(Graph& g, int from, int to, int cost = 1) {
    g[from].push_back(Edge(from, to, cost));
    g[to].push_back(Edge(to, from, cost));
    return;
}

// 有向
void connect(Graph& g, int from, int to, int cost = 1) {
    g[from].push_back(Edge(from, to, cost));
    return;
}

vector<i64> dijkstra(const Graph& g, int start) {
    const auto inf = numeric_limits<i64>::max();
    vector<i64> dist(g.size(), inf);

    using Pi = pair<i64, int>;
    priority_queue<Pi, vector<Pi>, greater<Pi>> que;
    dist[start] = 0;
    que.push(make_pair(0, 0));
    while (!que.empty()) {
        const auto e    = que.top();
        const auto cost = e.first;
        const auto from = e.second;
        que.pop();
        if (dist[from] < cost) continue;

        for (const auto& e : g[from]) {
            const auto next_cost = e.cost + cost;
            if (chmin(dist[e.to], next_cost)) {
                que.push(make_pair(next_cost, e.to));
            }
        }
    }

    return dist;
}

//---------------------------------------------------------------------------------------------------

signed main() {
    int N;
    cin >> N;
    Graph G(N);
    rep(i, 0, N) {
        int u, k;
        cin >> u >> k;
        rep(j, 0, k) {
            int v, c;
            cin >> v >> c;
            connect(G, u, v, c);
        }
    }
    auto dist = dijkstra(G, 0);
    rep(i, 0, N) {
        cout << i << " " << dist[i] << "\n";
    }
}

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

using namespace std;

#define llong long long 
typedef pair<long int, int> P;
long int d[10001];
bool Dec[10001];
vector<P> edges[10001];
priority_queue<P, vector<P>, greater<P> > q;

void solve(){
	fill_n(d, 10001, 9999999);
	d[0] = 0;
	fill_n(Dec, 10001, false);
	q.push(P(0,0));

	while(!q.empty()){
		P p = q.top(); q.pop();
		if(Dec[p.second] == true) continue;
		Dec[p.second] = true;
		d[p.second] = p.first;

		for(int i = 0; i < edges[p.second].size(); i++){
			P e = edges[p.second][i];
			if(d[e.second] > p.first + e.first){
				q.push(P(p.first + e.first, e.second));
			}
		}
	}

	return;
}

int main(){
	int N;
	cin >> N;
	for(int i = 0; i < N; i++){
		int num;
		int howedge;
		cin >> num >> howedge;
		for(int j = 0; j < howedge; j++){
			int to;
			long int cost;
			cin >> to >> cost;
			edges[num].push_back(P(cost, to));
		}
	}

	solve();

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

	return 0;
}

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 d[MAX],color[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;
                PQ.push(make_pair(d[v]*(-1),v));
                color[v]=GRAY;
            }
            }
        }
     
     
    for(int i=0;i<n;i++){
      cout<<i<< " "<<(d[i]==INFTY ?-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;
     
     
}