Go: package main

import (
	"strconv"
	"fmt"
	"bufio"
	"os"
)
const INF = 1 << 21
var scanner = bufio.NewScanner(os.Stdin)

func nextInt() int {
	scanner.Scan()
	i, e := strconv.Atoi(scanner.Text())
	if e != nil {
		panic(e)
	}
	return i
}


func main() {
	scanner.Split(bufio.ScanWords)
	n := nextInt()
	adj := make([][]int, n)
	for i := range adj {
		adj[i] = make([]int, n)
	}

	for i := 0;i < n; i++ {
		u := nextInt()
		k := nextInt()
		for j := 0; j < k; j++ {
			v := nextInt()
			c := nextInt()
			adj[u][v] = c
		}
	}

	// for i := range adj {
	// 	fmt.Println(adj[i])
	// }

	dist := make([]int, n)
	prev := make([]int, n)
	visited := make([]bool, n)
	dijkstra := func(start int, size int) {
		for i := 0; i < size; i++ {
			dist[i] = INF
			prev[i] = -1
			visited[i] = false
		}
		dist[start] = 0
		for {
			u := -1
			tmp_min := INF
			for i := 0; i < size; i++ {
				if visited[i] == false && dist[i] < tmp_min {
					tmp_min = dist[i]
					u = i
				}
			}
			if u == -1 {
				break
			}
			visited[u] = true
			for i := 0; i < size; i++ {
				if adj[u][i] > 0 {
					w := adj[u][i]
					newlen := dist[u] + w
					if newlen < dist[i] {
						dist[i] = newlen
						prev[i] = u
					}
				}
			}
		}
	}
	dijkstra(0, n)
	for i, cost := range dist {
		fmt.Printf("%d %d\n", i, cost)
	}
}

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

#define rep( i ,end ) for( int i = 0 ; i < end ; ++i )
#define Nmax 100
#define INF ( INT_MAX / 10 )

int Node[ Nmax ][ Nmax ] ;

int min( int a ,int b )
{
	return a > b ? b : a ;
}

void Init( int NODE[ Nmax ][ Nmax ] ,int N )
{
	rep( i ,N )
	{
		rep( j ,N )
		{
			NODE[ i ][ j ] = ( i == j ) ? 0 : INF ;
		}
	}
}



int main( void )
{
	int N ,V ,K ;
	int v ,cost ;
	scanf( "%d" ,&N ) ;

	Init( Node ,N ) ;

	rep( i ,N )
	{
		scanf( "%d %d" ,&V ,&K ) ;

		rep( j ,K )
		{
			scanf( "%d %d" ,&v ,&cost ) ;

			Node[ V ][ v ] = cost ;
		}
	}

	rep( u ,N )
	{
		rep( i ,N )
		{
			rep( j ,N )
			{
				Node[ i ][ j ] = min( Node[ i ][ j ] ,Node[ i ][ u ] + Node[ u ][ j ] ) ;
			}
		}
	}

	rep( u ,N )
	{
		printf( "%d %d\n" ,u ,Node[ 0 ][ u ] ) ;
	}

	return 0 ;
}

C++: #include<iostream>
#include<vector>
#include<map>
#include<set>
#include<tuple>
#include<climits>
#include<queue>
using namespace std;
#define int long long
vector<double> dijk(vector<tuple<int,int,double>> edge_list, int start){
        const int DJMAX = INT_MAX;
        set<int> node_list;
        for(auto edge : edge_list){
                node_list.insert(get<0>(edge));
                node_list.insert(get<1>(edge));
        }
        int nodenum = *node_list.rbegin()+1;
        vector<vector<double>> cost_map(nodenum, vector<double>(nodenum, DJMAX));
        for(auto edge : edge_list){
                cost_map[get<0>(edge)][get<1>(edge)] = get<2>(edge);
                cost_map[get<1>(edge)][get<0>(edge)] = get<2>(edge);
        }
        vector<double> cost(nodenum,DJMAX);
        cost[start] = 0;
        vector<int> visited(nodenum,0);
        priority_queue<pair<int,int>> que;
        que.push(pair<double,int>(0,start));
        while(!que.empty()){
                int s = que.top().second;
                que.pop();
                visited[s] = 1;
                for(int j=0;j<nodenum;j++){
                        if(visited[j]==1) continue;
                        double nc = cost[s]+cost_map[s][j];
                        if(nc<cost[j]){
                                cost[j] = nc;
                                que.push(pair<double,int>(-cost[j],j));
                        }
                }
        }
        return cost;
}
signed main(){
        int n;
        cin >> n;
        vector<tuple<int, int, double>> edges;
        for(int i=0;i<n;i++){
                int vs, vn;
                cin >> vs >> vn;
                for(int j=0;j<vn;j++){
                        int vt,c;
                        cin >> vt >> c;
                        edges.push_back(tuple<int,int,double>(vs,vt,c));
                }
        }
        auto ans = dijk(edges, 0);
        for(int i=0;i<n;i++){
                cout << i << " " << ans[i] << endl;
        }
        return 0;
}

C++: #include<iostream>
#include<vector>
#include<queue>
using namespace std;
template< typename FirstType, typename SecondType >
struct PairComparator {
  bool operator()( const pair<FirstType, SecondType>& p1, const pair<FirstType, SecondType>& p2 ) const 
    {  
		return p1.first > p2.first;
    }
};
bool inMST(vector< std::pair<int,int> > & MST,int j) {
	for (int k=0;k<(int)MST.size();++k){
		if(j == MST[k].second)
			return true;
	}
	return false;
}
int main(){
	int n;
	cin >> n;
	vector<int> E(n*n,-1);
	vector<int> DPG(n,-1);
	vector< std::pair<int,int> > MST;
	for(int j=0;j<n;++j) {
		int u,k; 
		cin >> u >> k;
		for(int i=0;i<k;++i){
			int v,c;
			cin >> v >> c;
			E[u*n+v] = c;
		}
	}
	priority_queue<pair<int,pair<int,int> >,vector< pair<int,pair<int,int> > >,
		PairComparator<int,pair<int,int> > > r;

	int cost = 0;
	int i=0;
	MST.push_back(pair<int,int>(i,i));
	DPG[i] = 0;
	while((int)MST.size() < n) {
		int ii=i*n;
		for (int j=0;j<n;++j) {
			if (E[ii+j] >= 0) {
				pair<int,int> add = std::make_pair(i,j);
				if (!inMST(MST,add.second)){
					r.push(std::pair<int,std::pair<int,int> >(E[ii+j],add));
				}
			}
		}
		pair<int,pair<int,int> > top;
		while (!r.empty()) {
			top = r.top();
			r.pop();
			if (!inMST(MST,top.second.second)){
				break;
			}
		}
		cost += top.first;
		MST.push_back(top.second);
		i = top.second.second;
		if (DPG[top.second.first] < 0){
			::_DEBUG_ERROR("invalid");
		}
		DPG[i] = DPG[top.second.first] + top.first;
		for(int j=0;j<n;++j){
			if (DPG[j] < 0)continue;
			if (E[i*n+j] < 0)continue;
			DPG[j] = std::min(DPG[j],DPG[i] + E[i*n+j]);
		}
	}
	for (int j=0;j<n;++j) {
		cout << j << " " <<  DPG[j] << endl;
	}
}