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()

	list := make([][]int, n)
	weight := make([]int, n)
	for i := range list {
		list[i] = make([]int, n)
		weight[i] = NIL
		for j := range list[i] {
			list[i][j] = NIL
		}
	}

	for i := 0; i < n; i++ {
		u := scanInt()
		k := scanInt()
		for j := 0; j < k; j++ {
			v := scanInt()
			w := scanInt()
			list[u][v] = w
		}
	}

	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 i, w := range list[node.id] {
			if w == NIL {
				continue
			}
			heap.Push(h, Node{id: i, weight: w + node.weight})
		}
	}

	w := bufio.NewWriter(os.Stdout)
	for i := 0; i < n; i++ {
		fmt.Fprint(w, i)
		fmt.Fprint(w, " ")
		fmt.Fprint(w, weight[i])
		fmt.Fprintln(w)
	}
	w.Flush()
}

C++: #include <stdio.h>
#include <stdint.h>
#include <iostream>
#include <fstream>
#include <cassert>
#include <climits>

#include <queue>
#include <memory>
using namespace std;

#define DEBUG (0)

#if DEBUG
#define DPRINTF(...) do { \
    printf("D(L%d) %s: ", __LINE__, __func__); \
    printf(__VA_ARGS__); \
  } while (false)
#else
#define DPRINTF(...)
#endif // DEBUG


const int kMaxVertex = 100;
int g_num_of_vertex;
int g_min_weight[kMaxVertex];


enum State {
    kUnvisited = 0,
    kVisited,
};


struct Edge {
    Edge(int num_vertex)
        : num_vertex_(num_vertex)
    {
        const int size_of_ptr_ = num_vertex_ * num_vertex_;
        weight_ = unique_ptr<int>(new int[size_of_ptr_]);

        for (int i = 0; i < num_vertex_; i++)
            for (int j = 0; j < num_vertex_; j++)
                setWeight(i, j, kInvalidWeight);

        for (int i = 0; i < num_vertex_; i++)
            setWeight(i, i, 0);
    }

    const int kInvalidWeight = INT_MAX;

    bool isConnected(int v0, int v1) const;
    vector<int> getConnectedVertices(int v) const;
    int getWeight(int v0, int v1) const;
    void setWeight(int v0, int v1, int w);

    void printWeight() const;

    int num_vertex_;
    int size_of_ptr_;
    unique_ptr<int> weight_;
};

bool Edge::isConnected(int v0, int v1) const
{
    if (v0 == v1)
        return false;

    if (getWeight(v0, v1) == kInvalidWeight)
        return false;

    return true;
}

vector<int> Edge::getConnectedVertices(int v) const
{
    vector<int> vertices;

    for (int i = 0; i < num_vertex_; i++)
        if (isConnected(v, i))
            vertices.push_back(i);

    return vertices;
}

void Edge::setWeight(int v0, int v1, int w)
{
    assert(0 <= v0 && v0 < num_vertex_);
    assert(0 <= v1 && v1 < num_vertex_);

    int *p = weight_.get() + (v0 * num_vertex_) + v1;
    *p = w;
}

int Edge::getWeight(int v0, int v1) const
{
    int *p = weight_.get() + (v0 * num_vertex_) + v1;
    return *p;
}

void Edge::printWeight() const
{
    DPRINTF("\n");
    for (int i = 0; i < num_vertex_; i++)
    {
        printf("    [%d]", i);
        for (int j = 0; j < num_vertex_; j++)
        {
            printf(" %d", getWeight(i, j));
        }
        cout << endl;
    }
}


struct VtxAndWeight {
    VtxAndWeight(int vtx, int weight)
        : vtx_(vtx)
        , weight_(weight)
    {}

    int vtx_;
    int weight_;
};


void calcShortestPath(int start, const Edge &edge)
{
    DPRINTF("start %d\n", start);
    assert(0 <= start && start < g_num_of_vertex);

    int current = start;
    int weight = 0;

    queue<VtxAndWeight> que;
    que.push(VtxAndWeight(current, weight));

    while (!que.empty())
    {
        VtxAndWeight vw = que.front();
        que.pop();

        int vtx = vw.vtx_;
        int weight = vw.weight_;

        DPRINTF("vtx %d  weight %d\n", vtx, weight);

        if (weight > g_min_weight[vtx])
        {
            continue;
        }
        g_min_weight[vtx] = weight;

        vector<int> connectedVertices = edge.getConnectedVertices(vtx);

        // update weight
        // push to queue as the next vertex to be visited
        for (int next_vtx : connectedVertices)
        {
            int next_weight = weight + edge.getWeight(vtx, next_vtx);
DPRINTF("next_vtx %d  next_weight %d\n", next_vtx, next_weight);
            que.push(VtxAndWeight(next_vtx, next_weight));
        }

    }

}


int main()
{
    cin >> g_num_of_vertex;
    cin.ignore();

    // init
    for (int i = 0; i < g_num_of_vertex; i++)
    {
        g_min_weight[i] = INT_MAX;
    }

    Edge edge(g_num_of_vertex);

    // input
    for (int i = 0; i < g_num_of_vertex; i++)
    {
        int start, degree;
        cin >> start >> degree;

        for (int j = 0; j < degree; j++)
        {
            int dst, weight;
            cin >> dst >> weight;

            edge.setWeight(start, dst, weight);
        }

        cin.ignore();
    }

#if DEBUG
    edge.printWeight();
#endif

    // process
    const int start = 0;
    calcShortestPath(start, edge);

    // output
    for (int i = 0; i < g_num_of_vertex; i++)
        printf("%d %d\n", i, g_min_weight[i]);

    return 0;
}

C++: #include <iostream>
#define WHITE 0
#define GRAY 1
#define BLACK 2
#define MAX_N 101
#define INF 100000000
using namespace std;

int m[MAX_N][MAX_N];
int d[MAX_N];
int color[MAX_N];

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

  d[s] = 0;
  color[s] = GRAY;

  while (true) {
    int mincost = INF;
    int u = -1;
    for (int i = 0; i < n; i++) {
      if (color[i] != BLACK && d[i] < mincost) {
	mincost = d[i];
	u = i;
      }
    }
    
    if (mincost == INF) break;
    
    color[u] = BLACK;
    for (int v = 0; v < n; v++) {
      if (color[v] != BLACK && m[u][v] != INF) {
	if (d[u] + m[u][v] < d[v]) {
	  d[v] = d[u] + m[u][v];
	  color[v] = GRAY;
	}
      }
    }
  }
}

void init(int n) {
  for (int i = 0; i < n; i++) {
    for (int j = 0; j < n; j++) {
      m[i][j] = INF;
    }
  }
}

int main() {
  int n;
  cin >> n;

  init(n);
  
  for (int i = 0; i < n; i++) {
    int u, k;
    cin >> u >> k;
    for (int i = 0; i < k; i++) {
      int v, c;
      cin >> v >> c;
      m[u][v] = c;
    }
  }

  dijkstra(0, n);

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

  return 0;
}

C++: #include <map>
#include <vector>
#include <cstdio>
using namespace std;
int main(){
	int n=0,N,i,j,k,c;
	scanf("%d",&N);
	vector<map<int,int> >dist(N);
	vector<bool>used(N);
	vector<int>cost(N);
	for(;n<N;n++){
		cost[n]=9999999;
		for(scanf("%d%d",&i,&k);k--;dist[i][j]=c)scanf("%d%d",&j,&c); //i->j cost c
	}
	for(cost[0]=0;;){ //dijkstra
		int m=9999999;
		for(i=0;i<N;i++)if(!used[i]&&m>cost[i])m=cost[i];
		if(m==9999999)break;
		for(j=0;j<N;j++)if(m==cost[j]){
			map<int,int>::iterator it=dist[j].begin();
			for(used[j]=1;it!=dist[j].end();it++)if(cost[it->first]>it->second+cost[j])cost[it->first]=it->second+cost[j];
		}
	}
	for(i=0;i<n;i++)printf("%d %d\n",i,cost[i]);
}