Go: package main

import (
	"bufio"
	"fmt"
	"os"
	"strconv"
)

const (
	MAX_N      = 100
	MAX_WEIGHT = 100000
)

type Edge struct {
	start  int
	end    int
	weight int
}

type ShortestInfo struct {
	edges    []Edge
	shortest int
}

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

	n, err := nextInt(sc)
	if err != nil {
		panic(err)
	}

	shortestList := make([]ShortestInfo, n)
	for i := 1; i < n; i++ {
		shortestList[i] = ShortestInfo{edges: []Edge{}, shortest: MAX_N*MAX_WEIGHT + 1}
	}

	adjacentMatrix, err := createAdjacentMatrix(n, sc)
	if err != nil {
		panic(err)
	}

	sssp([]int{1}, shortestList, adjacentMatrix)
	for _, v := range shortestList {
		fmt.Printf("%d %d\n", v.getEnd()-1, v.shortest)
	}
}

func (si ShortestInfo) getEnd() int {
	if len(si.edges) == 0 {
		return 1
	} else {
		return si.edges[len(si.edges)-1].end
	}
}

func createAdjacentMatrix(n int, sc *bufio.Scanner) ([][]int, error) {
	adjacentMatrix := make([][]int, n)
	for i := 0; i < n; i++ {
		id, err := nextInt(sc)
		if err != nil {
			return nil, err
		}
		adjacentMatrix[id] = make([]int, n)
		for j := 0; j < n; j++ {
			adjacentMatrix[id][j] = -1
		}
		vertexNum, err := nextInt(sc)
		if err != nil {
			return nil, err
		}
		for j := 0; j < vertexNum; j++ {
			v, err := nextInt(sc)
			if err != nil {
				return nil, err
			}
			c, err := nextInt(sc)
			if err != nil {
				return nil, err
			}
			adjacentMatrix[id][v] = c
		}
	}
	return adjacentMatrix, nil
}

func sssp(nodeStack []int, shortestList []ShortestInfo, adjacentMatrix [][]int) {
	for len(nodeStack) > 0 {
		currentNode := nodeStack[0]
		nodeStack = nodeStack[1:]
		currentShortest := getShortest(currentNode, shortestList)
		adjacents := findAdjacents(currentNode, adjacentMatrix)
		for i := 0; i < len(adjacents); i++ {
			adj := adjacents[i]
			if currentShortest.shortest+adj.weight < getShortest(adj.end, shortestList).shortest {
				setShortest(adj.end, adj, currentShortest, shortestList)
				nodeStack = append(nodeStack, adj.end)
			}
		}
	}
}

func getShortest(node int, shortestList []ShortestInfo) ShortestInfo {
	return shortestList[node-1]
}

func setShortest(node int, edge Edge, currentShortest ShortestInfo, shortestList []ShortestInfo) {
	newEdges := make([]Edge, len(currentShortest.edges)+1)
	for i := 0; i < len(newEdges)-1; i++ {
		newEdges[i] = currentShortest.edges[i]
	}
	newEdges[len(newEdges)-1] = edge
	shortestInfo := ShortestInfo{edges: newEdges, shortest: currentShortest.shortest + edge.weight}
	shortestList[node-1] = shortestInfo
}

func findAdjacents(currentNode int, adjacentMatrix [][]int) []Edge {
	adjacents := adjacentMatrix[currentNode-1]
	edges := []Edge{}
	for i, v := range adjacents {
		if v > 0 {
			edges = append(edges, Edge{start: currentNode, end: i + 1, weight: v})
		}
	}
	return edges
}

func nextInt(sc *bufio.Scanner) (int, error) {
	sc.Scan()
	return strconv.Atoi(sc.Text())
}

C++: #define _CRT_SECURE_NO_WARNINGS
#include <cstdio>
#include <cstdlib>
#include <string>
#include <iostream>
#include <climits>
#include <list>
#include <queue>

using namespace std;

static const int INFTY = -1;

int H;
int A[101];
int NodeNum[101];
int IndexInA[100];


int parent(int i) {
	return i / 2;
}

int left(int i) {
	return 2 * i;
}

int right(int i) {
	return 2 * i + 1;
}

void minHeapify(int i) {
	int l = left(i);
	int r = right(i);
	int smallest = i;
	if (l <= H && A[l] < A[i]) {
		smallest = l;
	}
	if (r <= H && A[r] < A[smallest]) {
		smallest = r;
	}
	if (smallest != i) {
		int temp = A[i];
		A[i] = A[smallest];
		A[smallest] = temp;
		temp = NodeNum[i];
		NodeNum[i] = NodeNum[smallest];
		NodeNum[smallest] = temp;
		IndexInA[NodeNum[i]] = i;
		IndexInA[NodeNum[smallest]] = smallest;

		minHeapify(smallest);
	}
}

void insert(int d, int nodeNum) {
	int i = ++H;
	A[i] = d;
	NodeNum[i] = nodeNum;
	IndexInA[nodeNum] = i;
	int p = parent(i);
	while (i > 1 && A[p] > A[i]) {
		int temp = A[p];
		A[p] = A[i];
		A[i] = temp;
		temp = NodeNum[p];
		NodeNum[p] = NodeNum[i];
		NodeNum[i] = temp;
		IndexInA[NodeNum[p]] = p;
		IndexInA[NodeNum[i]] = i;
		i = p;
		p = parent(i);
	}
}

int heapExtractMinNodeNum() {
	int minNodeNum = NodeNum[1];
	A[1] = A[H];
	NodeNum[1] = NodeNum[H];
	IndexInA[NodeNum[1]] = 1;
	H--;
	minHeapify(1);

	return minNodeNum;
}

void decrese(int i, int value) {
	A[i] = value;
	int p = parent(i);
	while (i > 1 && A[p] > A[i]) {
		int temp = A[p];
		A[p] = A[i];
		A[i] = temp;
		temp = NodeNum[p];
		NodeNum[p] = NodeNum[i];
		NodeNum[i] = temp;
		IndexInA[NodeNum[p]] = p;
		IndexInA[NodeNum[i]] = i;
		i = p;
		p = parent(i);
	}
}

int main() {
	int Dist[100];
	int AdjacenceyList[100][100];
	int AdjacenceyWeightList[100][100];
	int Degree[100];
	int i, j;
	int N;
	int W;
	//int Deg;
	int MinTotalWeight = 0;
	int u, v;
	int k;
	bool inT[100];

	cin >> N;

	//for (i = 0; i < N; i++) {
	//	inT[i] = false;
	//	Dist[i] = INFTY;
	//	Deg = -1;
	//	for (j = 0; j < N; j++) {
	//		cin >> W;
	//		if (W != -1) {
	//			AdjacenceyList[i][++Deg] = j;
	//			AdjacenceyWeightList[i][Deg] = W;
	//		}
	//	}
	//	Degree[i] = Deg + 1;
	//}

	for (i = 0; i < N; i++) {
		inT[i] = false;
		Dist[i] = INFTY;
		cin >> u >> k;
		Degree[u] = k;
		for (j = 0; j < k; j++) {
			cin >> AdjacenceyList[u][j] >> AdjacenceyWeightList[u][j];
		}
	}


	H = 0;
	u = 0;
	inT[u] = true;
	Dist[u] = 0;
	for (i = 1; i <= N - 1; i++) {
		for (j = 0; j < Degree[u]; j++) {
			v = AdjacenceyList[u][j];
			if (inT[v] == false) {
				W = AdjacenceyWeightList[u][j];
				if (Dist[v] == INFTY) {
					//Dist[v] = W;
					//insert(W, v);
					Dist[v] = Dist[u] + W;
					insert(Dist[v], v);
				}
				//else if (W < Dist[v]) {
				else if(W + Dist[u] < Dist[v]){
					//Dist[v] = W;
					//decrese(IndexInA[v], W);
					Dist[v] = W + Dist[u];
					decrese(IndexInA[v], Dist[v]);
				}
			}
		}

		int minNodeNum = heapExtractMinNodeNum();
		inT[minNodeNum] = true;
		//MinTotalWeight += Dist[minNodeNum];
		u = minNodeNum;

	}

	//printf("%d\n", MinTotalWeight);

	for (i = 0; i < N; i++) {
		printf("%d %d\n", i, Dist[i]);
	}

	return 0;
}

C++: #include<bits/stdc++.h>
using namespace std;
vector<int> color;//0:白1:灰2:黒
vector<vector<int>> M;
vector<int> d;
vector<int> p;
typedef long long int Int;

const int INF = 10000000;
int n;
void dijkstra(int s){
    
    for(int i=0;i<n;i++){
        d[i] = INF;
    }
    d[s] = 0;
    p[s] = -1;

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

int main(){
    cin >> n;
    color.assign(n,0);//0:白1:灰2:黒
    M.assign(n,vector<int>(n,INF));
    d.resize(n);
    p.resize(n);
    for(int i=0;i<n;i++){
        int id,k;cin >> id >> k;
        for(int j=0;j<k;j++){
            int v,cost;cin >> v >> cost;
            M[id][v] = cost;
        }
    }
    dijkstra(0);
    for(int i=0;i<n;i++){
        cout << i << " ";
        cout << d[i] << endl;
    }
}