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<iostream>
#include<algorithm>
#include<vector>
#define MAX 101
#define INF 100001
using namespace std;

int n, isSelected[MAX], dist[MAX];
vector<pair<int, int>> ver[MAX];

void initDijkstra(void);
void dijkstra(void);
bool doesFinished(void);

int main() {
	int i, j, id, k, v, c;
	cin >> n;
	for (i = 0; i < n; i++) {
		cin >> id >> k;
		for (j = 0; j < k; j++) {
			cin >> v >> c;
			ver[id].push_back(make_pair(v, c));
		}
	}

	initDijkstra();

	while (!doesFinished())dijkstra();

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

	return 0;
}

void initDijkstra(void) {

	dist[0] = 0;
	isSelected[0] = 1;
	for (int i = 1; i <= n; i++)dist[i] = INF;

	vector<pair<int, int>>::iterator itv;

	for (itv = ver[0].begin(); itv != ver[0].end(); itv++) {
		dist[itv->first] = itv->second;
	}

}

void dijkstra(void) {
	int i, minu, mindist = INF;
	vector<pair<int, int>>::iterator itv;

	for (i = 0; i < n; i++) {
		if (isSelected[i] == 0)continue;
		for (itv = ver[i].begin(); itv != ver[i].end(); itv++){
			if (isSelected[itv->first] == 1)continue;
			if (itv->second < mindist) {
				mindist = itv->second;
				minu = itv->first;
			}
		}
	}
	isSelected[minu] = 1;
	//dist[minu] = dist[minp] + mindist;
	for (itv = ver[minu].begin(); itv != ver[minu].end(); itv++) {
		if (isSelected[itv->first] == 1)continue;
		dist[itv->first] = min(dist[minu] + itv->second, dist[itv->first]);
	}
}

bool doesFinished(void) {
	for (int i = 0; i < n; i++) {
		if (isSelected[i] == 0)return false;
	}
	return true;
}

C++: #include <iostream>
#include <algorithm>
#include <cmath>
#include <cstdio>
using namespace std;
#define MAX 10000000

int b[110];

int solve(int a[110][110], int n){
	b[0] = 0;
	for(int i = 0;i < n;i++){
		for(int j = 1;j < n;j++){
			//if(j == 4)cout << b[4] << i << " " << endl;
			if(a[i][j] != -1)b[j] = min(b[j], a[i][j]+b[i]);
			//if(j == 4)cout << b[4] << i << " " << endl;
		}
	}
	//cout << endl;
	return 0;
}

int main(){
	int a[110][110], n;
	fill((int*)a, (int*)(a+110), -1);
	fill(b, b+110, MAX);
	cin >> n;
	for(int i = 0;i < n;i++){
		int u, k, c, d;
		cin >> u >> k;
		for(int j = 0;j < k;j++){
			cin >> c >> d;
			a[u][c] = a[c][u] = d;
		}
	}
	for(int i = 0;i < n;i++)solve(a, n);
	for(int i = 0;i < n;i++){
		cout << i << " " << b[i] << endl;
	}
	
	return 0;
}
/*
5
0 3 2 3 3 1 1 2
1 2 0 2 3 4
2 3 0 3 3 1 4 1
3 4 2 1 0 1 1 4 4 3
4 2 2 1 3 3
*/

C++: #include <iostream>

using namespace std;
int n;
int dat[100][100];
int cost[100];
int done[100];

void prim(){
	for(int i=0;i<n;i++){
		cost[i]=1<<21;
		done[i]=0;
	}
	int s=0;	
	int next, ncost=1<<21;
	done[s]=1;
	cost[s]=0;
	while(1){
		ncost=1<<21;
		for(int j=0;j<n;j++){
			if(done[j]){
				for(int i=0;i<n;i++){
					if(dat[j][i]!=-1){
						if(cost[i]>=dat[j][i]&&!done[i]){
							cost[i]=dat[j][i];
						}
						if(ncost>cost[i]&&!done[i]){
							next=i;
							ncost=cost[i];
						}
					}
				}
			}
		}
//		cout<<"next:"<<next<<" cost:"<<cost[next]<<endl;
		done[next]=1;
		int flag=true;
		for(int i=0;i<n;i++){
			if(!done[i]) flag = false;
		}
		if(flag)
			return;
	}
}


void dijk(){
	for(int i=0;i<n;i++){
		cost[i]=1<<21;
		done[i]=0;
	}
	int s=0;	
	int next, ncost=1<<21;
	done[s]=1;
	cost[s]=0;
	while(1){
		ncost=1<<21;
		for(int j=0;j<n;j++){
			if(done[j]){
				for(int i=0;i<n;i++){
					if(dat[j][i]!=0){
						if(cost[i]>=dat[j][i]+cost[j]){
							cost[i]=dat[j][i]+cost[j];
						}
						if(ncost>cost[i]&&!done[i]){
							next=i;
							ncost=cost[i];
						}
					}
				}
			}
		}
//		cout<<"next:"<<next<<" cost:"<<cost[next]<<endl;
		done[next]=1;
		int flag=true;
		for(int i=0;i<n;i++){
			if(!done[i]) flag = false;
		}
		if(flag)
			return;
	}
}


int main(){
	int num, from, dist, c;
	cin>>n;
	for(int i=0;i<n;i++){
		cin>>from>>num;
		for(int j=0;j<num;j++){
			cin>>dist>>c;
			dat[from][dist]=c;
		}
	}
	dijk();
	for(int i=0;i<n;i++){
		cout<<i<<" "<<cost[i]<<endl;
	}
	return 0;
}

C++: #include <bits/stdc++.h>
using namespace std;
#define FOR(i,k,n) for(int i = (k); i < (n); i++)
#define REP(i,n) FOR(i,0,n)
#define INF 114514810
#define MOD 1000000007
#define ALL(a) begin(a),end(a)
#define MS(m,v) memset(m,v,sizeof(m))
#define D10  fixed<<setprecision(10)
typedef vector<int> vi;
typedef vector<string> vs;
typedef pair<int, int> P;
typedef long long ll;
struct edge
{
	int from, to, cost;
	bool operator < (const edge& e) const { return cost < e.cost; }
	bool operator >(const edge& e) const { return cost > e.cost; }
};
///*************************************************************************************///
///*************************************************************************************///
///*************************************************************************************///

int V;
int d[100001];
vector<edge> es[100001];

void dijkstra(int s)
{
	fill(d, d + V, INF);
	d[s] = 0;
	priority_queue<P, vector<P>, greater<P>> que;
	que.push(P(0, s));
	while (!que.empty())
	{
		P p = que.top(); que.pop();
		int v = p.second;
		if (d[v] < p.first) continue;
		REP(i, es[v].size())
		{
			edge e = es[v][i];
			if (d[e.to] > d[v] + e.cost)
			{
				d[e.to] = d[v] + e.cost;
				que.push(P(d[e.to], e.to));
			}
		}
	}
}

int main()
{
	cin >> V;
	REP(i, V)
	{
		int u, k; cin >> u >> k;
		REP(i, k)
		{
			int c, v; cin >> v >> c;
			es[u].push_back(edge{ u, v, c });
		}
	}
	dijkstra(0);
	REP(i, V)
	{
		cout << i << " " << d[i] << endl;
	}
	return 0;
}