Go: // ダイクストラのアルゴリズム
package main

import (
	"bufio"
	"fmt"
	"log"
	"math"
	"os"
	"strconv"
	"strings"
)

type color int

const (
	white color = iota // 未訪問
	mst                // MSTとして確定
)

// 頂点
type node struct {
	num     int         // 頂点の番号
	weights map[int]int // 重みMAP
	parent  *node       // MSTへの重み最小の親
	sum     int         // 始点からの距離
	color   color
}

func (p *node) getMinToMst() int {
	if p.parent == nil {
		return math.MaxInt32
	}
	return p.weights[p.parent.num]
}

func main() {
	scanner := bufio.NewScanner(os.Stdin)
	n := eGetInt(scanner)

	nodes := make([]*node, n)
	for i := 0; i < n; i++ {
		weights := eAtoi((strings.Fields(eGetline(scanner))))
		v := &node{weights[0], make(map[int]int, weights[1]), nil, 0, white}
		for j := 0; j < weights[1]; j++ {
			k := weights[j*2+2] // 相手の頂点名
			w := weights[j*2+3] // 重み
			v.weights[k] = w
		}
		nodes[i] = v
	}

	// 初回はnode[0]がMSTに入るように
	nodes[0].parent = nodes[0]

	for { // 全部チェックするまで

		// どの頂点を新たにMSTに取り込むか

		var minNode *node
		min := math.MaxInt32
		for _, v := range nodes {
			if v.color == mst {
				continue
			}
			if v.getMinToMst() < min {
				min = v.getMinToMst()
				minNode = v
			}
		}
		if minNode == nil {
			// すべて完了している.
			break
		}

		// MSTに追加する頂点決定
		minNode.color = mst
		// 自分の親の合計値と合算する
		minNode.sum = minNode.parent.sum + min

		// MSTに属していない頂点それぞれについて,MSTとの最小の重みの距離を加算
		for _, v := range nodes {
			if v.color == mst {
				continue
			}
			w, ok := v.weights[minNode.num]
			if !ok {
				// minNodeと接してない
				continue
			}

			if w < v.getMinToMst() {
				// minNodeへの距離がもっとも重みが少ないので親を変更
				v.parent = minNode
			}
		}
	}

	for i, v := range nodes {
		fmt.Printf("%d %d\n", i, v.sum)
	}
}

func eGetInt(scanner *bufio.Scanner) int {
	t := eAtoi(strings.Fields(eGetline(scanner)))
	return t[0]
}

func eGetline(p *bufio.Scanner) string {
	if !p.Scan() {
		if err := p.Err(); err != nil {
			log.Fatal(err.Error())
		}
		return ""
	}
	return p.Text()
}

func eAtoi(s []string) []int {
	ints := make([]int, len(s))
	var err error
	for i, e := range s {
		ints[i], err = strconv.Atoi(e)
		if err != nil {
			log.Fatal(err.Error())
		}
	}
	return ints
}

C++: #include<stdio.h>
#include<algorithm>
#define  INF  100000  
using namespace std;
typedef long long ll;
ll q[210][210];
int  p[210];
ll  dis[210];

void Dijkstra(int N){
	fill(dis,dis+210,INF);
	dis[0]=0;
	while(p[N-1]==0){
		int x=-1;
		ll mini=INF;
		for(int i=0;i<N;i++){
			if(p[i]==1) continue;
			if(mini>dis[i]){
				mini=dis[i];
				x=i;
			}
		}
		p[x]=1;
		for(int y=0;y<N;y++){
			if(p[y]==1)  continue;
			dis[y]=min(dis[y],dis[x]+q[x][y]);
		}
	}
}
 
int main()
{
    int u,N,k,v;
	ll C;
	while(~scanf("%d",&N))
	{
		fill(q[0],q[0]+210*210,INF);
		fill(p,p+210,0);
		int M=N;
		while(N--)
		{
		    scanf("%d%d%",&u,&k);
		    for(int i=0;i<k;i++){
		    	scanf("%d%lld",&v,&C);
		    	q[u][v]=min(q[u][v],C);
			    q[v][u]=q[u][v];
			}
		}
		Dijkstra(M);
		for(int i=0;i<M;i++){
			printf("%d %lld\n",i,dis[i]);
		}
	}
	return 0;
}

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

struct edge{
    long long from,to,cost;
    edge(){}
    edge(long long f,long long t,long long c) : from(f),to(t),cost(c){}
};

vector<long long> bellmanford(int s,const vector<edge>& es,int V){
    constexpr long long inf = 1ll << 60;
    vector<long long> d(V,inf);
    d[s] = 0;
    for(int i=0;i<V;i++){
        for(const edge& e : es){
            if(d[e.from]!=inf && d[e.to]>d[e.from]+e.cost){
                d[e.to] = d[e.from] + e.cost;
            }
        }
    }
    return d;
}

signed main(){
    int n;cin>>n;
    vector<edge> es;
    for(int i=0;i<n;i++){
        int u,k;
        cin >> u >> k;
        for(int j=0;j<k;j++){
            int c,v;
            cin >> v >> c;
            es.emplace_back(edge(u,v,c));
        }
    }
    auto d = bellmanford(0,es,n);
    for(int i=0;i<n;i++){
        cout << i <<  " " << d[i] << endl;
    }
}

C++: #include<iostream>
#include<cstdio>
#include<cstring>
#define INF 9999
using namespace std;
int n;
int A[1000][1000];
int d[1000];
bool used[1000];
int D[1000][1000];
 
void Init(int f){
  for(int i=0;i<f;i++){
    for(int j=0;j<f;j++)D[i][j] = INF;
  }
 
}
 
int main(){
  scanf("%d",&n);
  int u,k,C,V;
  Init(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);
    D[u][V] = C;
    D[V][u] = C;
      }     
  }
   
  for(int i=0;i<n;i++)D[i][i] = 0;
  for(int k=0;k<n;k++)for(int i=0;i<n;i++)for(int j=0;j<n;j++)D[i][j] = min(D[i][j],D[i][k] + D[k][j]); 
  for(int i=0;i<n;i++){
    printf("%d %d\n",i,D[0][i]);
  }
 
  return 0;
}

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

int n, M[MAX][MAX];

void dijkstra(){
    int minv;
    int d[MAX],color[MAX];
    
    for( int i = 0; i < n; i++ ){
        d[i] = INFTY;
        color[i] = WHITE;
    }
    
    d[0] = 0;
    color[0] = GRAY;
    while(1){
        minv = INFTY;
        int u = -1;
        for( int i = 0; i < n; i++ ){
            if(minv > d[i] && color[i] != BLACK ){
                u = i;
                minv = d[i];
            }
        }
        if( u == -1 ) break;
        color[u] = BLACK;
        for( int v = 0; v < n; v++ ){
            if( color[v] != BLACK && M[u][v] != INFTY ){
                if( d[v] > d[u] + M[u][v] ){
                    d[v] = d[u] + M[u][v];
                    color[v] = GRAY;
                }
            }
        }
    }
    for( int i = 0; i < n; i++ ){
        cout << i << " " << ( d[i] == INFTY ? -1 : d[i] ) << endl;
    }
}

int main(){
    cin >> n;
    for( int i = 0; i < n; i++ ){
        for( int j = 0; j < n; j++ ){
            M[i][j] = INFTY;
        }
    }
    
    int k, c, u, v;
    for( int i = 0; i < n; i++ ){
        cin >> u >> k;
        for( int j = 0; j < k; j++ ){
            cin >> v >> c;
            M[u][v] = c;
        }
    }
    
    dijkstra();
    
    return 0;
}

C++: #include <cstdio>
#include <vector>

int main(void){

	int n, count, next_node, num_neighbors, min_distance;
	std::vector< std::vector<int> > edges;
	std::vector< std::vector<int> > neighbors;
	std::vector<bool> isUsed;
	std::vector<int> distance;
	scanf("%d", &n);
	edges.resize(n);
	isUsed.resize(n);
	neighbors.resize(n);
	distance.resize(n);
	for(int i=0;i<n;i++){
		scanf("%d %d", &next_node, &num_neighbors);
		edges[next_node].resize(num_neighbors);
		neighbors[next_node].resize(num_neighbors);
		for (int j=0;j<num_neighbors;j++){
			scanf("%d %d", &neighbors[next_node][j], &edges[next_node][j]);
		}
		isUsed[next_node]=-false;
		distance[next_node]=-1;
	}
	isUsed[0] = true;
	distance[0] = 0;
	count=0;
	for(int i=0;i<neighbors[0].size();i++){
		distance[neighbors[0][i]] = edges[0][i];
	}
	int neighbor;
	while(count<n-1){
		min_distance = 100000;
		for(int i=0;i<n;i++){
			if(!isUsed[i] && distance[i] != -1 && distance[i]<min_distance){
				next_node = i;
				min_distance = distance[i];
			}
		}
		isUsed[next_node] = true;
		for(int i=0;i<neighbors[next_node].size();i++){
			neighbor = neighbors[next_node][i];
			if(distance[neighbor] > distance[next_node]+edges[next_node][i] || distance[neighbor] <0){
				distance[neighbor] = distance[next_node] + edges[next_node][i];
			}
		}
		count ++;
	}
	for(int i=0;i<n;i++){
		printf("%d %d\n", i, distance[i]);
	}
	return 0;
}