Problem:
MathJax.Hub.Config({ tex2jax: { inlineMath: [["$","$"], ["\\(","\\)"]], processEscapes: true }});

Single Source Shortest Path II

For a given weighted graph $G = (V, E)$, find the shortest path from a source to each vertex. For each vertex $u$, print the total weight of edges on the shortest path from vertex $0$ to $u$.

Input

In the first line, an integer $n$ denoting the number of vertices in $G$ is given. In the following $n$ lines, adjacency lists for each vertex $u$ are respectively given in the following format:

$u$ $k$ $v_1$ $c_1$ $v_2$ $c_2$ ... $v_k$ $c_k$

Vertices in $G$ are named with IDs $0, 1, ..., n-1$. $u$ is ID of the target vertex and $k$ denotes its degree. $v_i (i = 1, 2, ... k)$ denote IDs of vertices adjacent to $u$ and $c_i$ denotes the weight of a directed edge connecting $u$ and $v_i$ (from $u$ to $v_i$).

Output

For each vertex, print its ID and the distance separated by a space character in a line respectively. Print in order of vertex IDs.

Constraints

$1 \leq n \leq 10,000$

$0 \leq c_i \leq 100,000$

$|E| < 500,000$

All vertices are reachable from vertex $0$

Sample Input 1

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

Sample Output 1

0 0
1 2
2 2
3 1
4 3

Reference

Introduction to Algorithms, Thomas H. Cormen, Charles E. Leiserson, Ronald L. Rivest, and Clifford Stein. The MIT Press.

Solution in C (judge verdict: Accepted)

#include <stdio.h>
#include <stdlib.h>

#define INIT_CAP 10
#define INF 1000000000

typedef struct {
	int to, w;
} Edge;

typedef struct {
	Edge *elem;
	int cap, size;
} VecEdge;

typedef struct {
	int num;
	int d;
} PairNumDis;

typedef struct {
	int d;
	int idx;
} Node;

VecEdge adj[10000];
PairNumDis heap[10000];
int hsize;
Node node[10000];

void init(int n) {
	while (n--)
		adj[n] = (VecEdge){malloc(sizeof(Edge) * INIT_CAP), INIT_CAP, 0};
}

void add(int from, int to, int w) {
	if (adj[from].size == adj[from].cap) {
		adj[from].cap <<= 1;
		adj[from].elem = realloc(adj[from].elem, sizeof(Edge) * adj[from].cap);
	}
	adj[from].elem[adj[from].size++] = (Edge){to, w};
}

int calcNextIdx(int i) {
	return i * 2 + 1 + (i * 2 + 2 < hsize && heap[i * 2 + 1].d > heap[i * 2 + 2].d);
}

PairNumDis delete(void) {
	int i;
	int nextIdx;
	const PairNumDis root = heap[0], last = heap[--hsize];

	for (i = 0; i * 2 + 1 < hsize && last.d > heap[nextIdx = calcNextIdx(i)].d; i = nextIdx) {
		heap[i] = heap[nextIdx];
		node[heap[i].num].idx = i;
	}
	heap[i] = last;
	node[last.num].idx = i;

	return root;
}

void decreaseKey(int num, int d) {
	int i;

	for (i = node[num].idx; i > 0 && d < heap[i - 1 >> 1].d; i = i - 1 >> 1) {
		heap[i] = heap[i - 1 >> 1];
		node[heap[i].num].idx = i;
	}
	heap[i] = (PairNumDis){num, d};
	node[num].idx = i;
}

void dijkstra(int n, int s) {
	int i;

	for (i = 0; i < n; i++) {
		heap[i] = (PairNumDis){i, INF};
		node[i] = (Node){INF, i};
	}
	hsize = n;

	node[s].d = 0;
	decreaseKey(s, 0);
	while (hsize > 0) {
		PairNumDis fromPair = delete();
		for (i = 0; i < adj[fromPair.num].size; i++) {
			Edge e = adj[fromPair.num].elem[i];
			if (fromPair.d + e.w < node[e.to].d) {
				node[e.to].d = fromPair.d + e.w;
				decreaseKey(e.to, node[e.to].d);
			}
		}
	}
}

int main(void) {
	int i, j;
	int n;

	scanf("%d", &n);

	init(n);
	for (i = 0; i < n; i++) {
		int u, k;
		scanf("%d %d", &u, &k);
		while (k--) {
			int v, c;
			scanf("%d %d", &v, &c);
			add(u, v, c);
			// add(v, u, c);
		}
	}

	dijkstra(n, 0);

	for (i = 0; i < n; i++)
		printf("%d %d\n", i, node[i].d);

	return 0;
}