Go: package main

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

type Node struct {
	Id int
	Dis int
}

type PriorityQueue []*Node

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

func (pq PriorityQueue) Less(i, j int) bool {
	return pq[i].Dis < pq[j].Dis
}

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

func (pq *PriorityQueue) Push(x interface{}) {
	*pq = append(*pq, x.(*Node))
}

func (pq *PriorityQueue) Pop() interface{} {
	n := len(*pq)
	pop := (*pq)[n-1]
	*pq = (*pq)[0:n-1]
	return pop
}

func main() {
	var n int
	fmt.Scan(&n)

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

	g := make([][]int, n)
	c := make([][]int, n)
	pq := make(PriorityQueue, 0, n)
	d := make([]int, n)
	for i := 0; i < n; i++ {
		sc.Scan()
		u, _ := strconv.Atoi(sc.Text())
		sc.Scan()
		k, _ := strconv.Atoi(sc.Text())
		g[u] = make([]int, k)
		c[u] = make([]int, k)
		for j := 0; j < k; j++ {
			sc.Scan()
			g[u][j], _ = strconv.Atoi(sc.Text())
			sc.Scan()
			c[u][j], _ = strconv.Atoi(sc.Text())
		}

		if u == 0 {
			d[u] = 0
		} else {
			d[u] = 1 << 30
		}
		pq.Push(&Node{u, d[u]})
	}
	heap.Init(&pq)

	for pq.Len() > 0 {
		node := heap.Pop(&pq).(*Node)
		for i := 0; i < len(g[node.Id]); i++ {
			nextId := g[node.Id][i]
			nextDis := node.Dis + c[node.Id][i]
			if nextDis < d[nextId] {
				d[nextId] = nextDis
				heap.Push(&pq, &Node{nextId, nextDis})
			}
		}
	}

	wr := bufio.NewWriter(os.Stdout)
	for i := 0; i < n; i++ {
		wr.WriteString(strconv.Itoa(i))
		wr.WriteString(" ")
		wr.WriteString(strconv.Itoa(d[i]))
		wr.WriteString("\n")
	}
	wr.Flush()
}

C++: #include <iostream>
#include <vector>
#include <map>
#include <queue>


void update(int node, std::vector<int>& weight, const std::vector<std::map<int, int>> link_list) {
    for (auto && l : link_list[node]) {
        if (weight[l.first] == -1 || weight[node] + l.second < weight[l.first]) {
            weight[l.first] = weight[node] + l.second;
            update(l.first, weight, link_list);
        }
    }
}


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

    std::vector<std::map<int, int>> link_list;
    for (int i = 0; i < n; i++) {
        int u, k;
        std::cin >> u >> k;
        std::map<int, int> map;
        for (int j = 0; j < k; j++) {
            int c, v;
            std::cin >> c >> v;
            map[c] = v;
        }
        link_list.emplace_back(map);
    }

    std::vector<int> weight(n, -1);
    weight[0] = 0;

    auto comp = [] (std::tuple<int, int, int> &lfs, std::tuple<int, int, int> &rhs) {
        return std::get<2>(lfs) > std::get<2>(rhs);
    };
    
    std::priority_queue<std::tuple<int, int, int>, std::vector<std::tuple<int, int, int>>, decltype(comp)> que(comp);
    for (auto && m : link_list[0]) {
        que.push(std::make_tuple(0, m.first, m.second));
    }

    while (!que.empty()) {
        auto val = que.top();
        que.pop();
        auto w = weight[std::get<0>(val)] + std::get<2>(val);
        if (weight[std::get<1>(val)] == -1 || w < weight[std::get<1>(val)]) {
            weight[std::get<1>(val)] = w;
            for (auto && m : link_list[std::get<1>(val)]) {
                que.push(std::make_tuple(std::get<1>(val), m.first, m.second));
            }
        }
    }

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

C++: #include <queue>
#include <cstdio>
#include <vector>
using namespace std;
int V, s, t, p, q, d[100000]; vector<pair<int, int> > G[100000];
int main() {
	scanf("%d", &V);
	for(int i = 0; i < V; i++) {
		scanf("%d%d", &s, &t);
		for(int j = 0; j < t; j++) {
			scanf("%d%d", &p, &q);
			G[i].push_back(make_pair(p, q));
		}
	}
	for(int i = 1; i < V; i++) d[i] = 999999999;
	priority_queue<pair<int, int> > que; que.push(make_pair(0, 0));
	while(!que.empty()) {
		int v = que.top().second; que.pop();
		for(int i = 0; i < G[v].size(); i++) {
			int u = G[v][i].first, w = G[v][i].second;
			if(d[u] > d[v] + w) {
				d[u] = d[v] + w;
				que.push(make_pair(-d[u], u));
			}
		}
	}
	for(int i = 0; i < V; i++) printf("%d %d\n", i, d[i]);
	return 0;
}

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

static const int Max = 100;
static const int Inf = 10000;
enum State {
	Not_Searched = 0,
	Connected = 1,
	Searched = 2
};

int n = 0;
vector<pair<int, int> > adj[Max]; // pair<??£??\??????index, ??????cost> 

void dijkstra() {
	priority_queue<pair<int, int> > pq; // pair<start ???????????????????????????????????§????????????????´???????idx>
	int st[Max];
	int min_cost[Max];
	for (int i = 0; i < n; i++) {
		st[i] = Not_Searched;
		min_cost[i] = Inf;
	}

	min_cost[0] = 0;
	pq.push(make_pair(0, 0));
	st[0] = Connected;

	while (!pq.empty()) {
		pair<int, int> f = pq.top();
		pq.pop();
		int u = f.second;
		st[u] = Searched;

		if (min_cost[u] < f.first * (-1)) continue;

		for (int i = 0; i < adj[u].size(); i++) {
			int adj_u_idx = adj[u][i].first;
			if (st[adj_u_idx] == Searched) continue;
			if (min_cost[adj_u_idx] > min_cost[u] + adj[u][i].second) {
				min_cost[adj_u_idx] = min_cost[u] + adj[u][i].second;
				pq.push(make_pair(min_cost[adj_u_idx]*(-1), adj_u_idx));
				st[adj_u_idx] = Connected;
			}
		}
	}
	for (int i = 0; i < n; i++) {
		cout << i << " " << (min_cost[i] == Inf ? -1 : min_cost[i]) << endl;
	}
	return;
}

int main() {
	cin >> n;
	int u, k, vi, ci;
	for (int i = 0; i < n; i++) {
		cin >> u >> k;
		for (int j = 0; j < k; j++) {
			cin >> vi >> ci;
			adj[u].push_back(make_pair(vi, ci));
		}
	}

	dijkstra();
	return 0;
}

C++: #include<iostream>
#include<algorithm>
#include<queue>
#include<vector>
#include<utility>
#include<limits>
using namespace std;
typedef pair<int, int> Edge;
int main()
{
	int n; cin >> n;
	vector< vector< Edge > > lists;

	for (int i = 0; i < n; i++)
	{
		vector<Edge> list;
		int u, k;
		cin >> u >> k;
		for (int j = 0; j < k; j++)
		{
			Edge edge;
			cin >> edge.second >> edge.first;
			list.push_back(edge);
		}
		lists.push_back(list);
	}

	vector<int> costs(n, INT32_MAX);
	costs[0] = 0;
	priority_queue<Edge> queue;
	for (Edge edge : lists[0])
		queue.push(edge);

	while (!queue.empty())
	{
		Edge edge = queue.top(); queue.pop();
		int dest = edge.second;
		int cost = edge.first;
		if (costs[dest] < cost)continue;
		int new_cost = costs[edge.second] = edge.first;

		for (Edge next : lists[dest])
		{
			next.first += new_cost;
			queue.push(next);
		}
	}
	for (int i = 0; i < n; i++)
		cout << i << " " << costs[i] << endl;

	char c;
	cin >> c;

	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,c,u,v;
  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;
}