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
 
inline int nextInt(void) {
    int ch;
    int sign, x;
 
    do {
        ch = getchar();
    } while (ch < '-');
 
    if (ch == '-') {
        sign = -1;
        ch = getchar();
    } else
        sign = 1;
 
    x = 0;
    while (ch >= '0' && ch <= '9') {
        x = x * 10 + ch - '0';
        ch = getchar();
    }
 
    return sign * x;
}
 
inline void printInt(int x) {
    char ch[10];
    int cnt;
 
    if (x < 0) {
        putchar('-');
        x = -x;
    }
 
    cnt = 0;
    do {
        ch[cnt++] = '0' + x % 10;
        x /= 10;
    } while (x);
 
    while (cnt--)
        putchar(ch[cnt]);
}
 
typedef struct {
    int to, w;
} Edge;
 
typedef struct {
    Edge *elem;
    int cap, size;
} VecEdge;
 
typedef struct {
    int num, d;
} PNumDis;
 
VecEdge adj[10000];
PNumDis heap[500000];
int hsize;
int d[10000];
 
void init(int n) {
    while (n--)
        adj[n] = (VecEdge){malloc(sizeof(Edge) * INIT_CAP), INIT_CAP, 0};
}
 
inline 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};
}
 
inline void insert(int num, int d) {
    int i;
    for (i = hsize++; i > 0 && d < heap[i - 1 >> 1].d; i = i - 1 >> 1)
        heap[i] = heap[i - 1 >> 1];
    heap[i] = (PNumDis){num, d};
}
 
inline int calcNextIdx(int i) {
    return i * 2 + 1 + (i * 2 + 2 < hsize && heap[i * 2 + 1].d > heap[i * 2 + 2].d);
}
 
inline PNumDis delete(void) {
    int i;
    int nextIdx;
    const PNumDis 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];
    heap[i] = last;
 
    return root;
}
 
void dijkstra(int n, int s) {
    int i;
 
    for (i = 0; i < n; i++)
        d[i] = INF;
 
    d[s] = 0;
    insert(s, 0);
    while (hsize > 0) {
        const PNumDis fromP = delete();
 
        if (fromP.d > d[fromP.num])
            continue;
 
        for (i = 0; i < adj[fromP.num].size; i++) {
            const Edge e = adj[fromP.num].elem[i];
            if (fromP.d + e.w < d[e.to]) {
                d[e.to] = fromP.d + e.w;
                insert(e.to, d[e.to]);
            }
        }
    }
}
 
int main(void) {
    int i;
    int n;
 
    scanf("%d", &n);
 
    init(n);
    for (i = 0; i < n; i++) {
        int u = nextInt(), k = nextInt();
        while (k--) {
            int v = nextInt(), c = nextInt();
            add(u, v, c);
        }
    }
 
    dijkstra(n, 0);
 
    for (i = 0; i < n; i++) {
        printInt(i);
        putchar(' ');
        printInt(d[i]);
        putchar('\n');
    }
 
    return 0;
}