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: Memory Limit Exceeded)

#include <stdio.h>
#include <limits.h>
#define MAX 10000
#define INFTY INT_MAX - 1
#define NIL -1
#define WHITE 0
#define GRAY 1
#define BLACK 2

typedef struct heap {
  int node_num;
  int cost;
}Vertex;

/* Global Variables */
int AM[MAX][MAX]; //Adjacency Matrix
int d[MAX], pi[MAX];
int color[MAX];
Vertex PQ[MAX]; //Priority Queue
int H, n;

/* min-Priority Queue Statements */
void heapDecreaseKey(int i, Vertex keydata) {
  Vertex temp;

  if (keydata.cost >= PQ[i].cost) return;

  PQ[i] = keydata;
  while ( i > 1 && PQ[i / 2].cost > PQ[i].cost ) {
    temp = PQ[i];
    PQ[i] = PQ[i / 2];
    PQ[i / 2] = temp;
    i /= 2;
  }
}

void insert(Vertex keydata) {
  H++;
  PQ[H].node_num = keydata.node_num;
  PQ[H].cost = INFTY;
  heapDecreaseKey(H, keydata);
}

void minHeapify(int i) {
  int left, right, min;
  Vertex temp;
  left = 2 * i;
  right = left + 1;

  if ( left <= H && PQ[left].cost < PQ[i].cost )
    min = left;
  else
    min = i;

  if ( right <= H && PQ[right].cost < PQ[min].cost )
    min = right;

  if ( min != i ) {
    temp = PQ[i];
    PQ[i] = PQ[min];
    PQ[min] = temp;
    minHeapify(min);
  }
}

Vertex extractMin() {
  Vertex minv;

  minv = PQ[1];
  PQ[1] = PQ[H--];
  minHeapify(1);

  return minv;
}

int isEmpty() {
  return ( H < 1 ) ? 1 : 0;
}

/* Dijkstra's Algorithm by Priority Queue */
void dijkstra(int s) {
  int u, v, j, i;
  Vertex ini;
  Vertex x;
  ini.node_num = s;
  ini.cost = 0;

  for ( u = 0; u < n; u++ ) {
    color[u] = WHITE;
    pi[u] = NIL;
    d[u] = INFTY;
  }
  d[s] = 0;

  insert(ini);
  color[s] = GRAY;

  while ( !isEmpty() ) {
    x = extractMin();
    u = x.node_num;
    color[u] = BLACK;
 
    if ( d[u] < x.cost ) continue;

    for ( j = 0; j < n; j++ ) {
      v = j;
      if ( color[v] != BLACK && AM[u][v] != INFTY ){
	if ( d[v] > d[u] + AM[u][v] ) {
	  d[v] = d[u] + AM[u][v];
	  ini.node_num = v;
	  ini.cost = d[v];
	  insert(ini);
	  color[v] = GRAY;
	}
      }
    }
  }

}

int main() {
  int i, j, k, u, v;

  scanf("%d", &n);

  //Initialize
  for ( i = 0; i < n; i++ )
    for ( j = 0; j < n; j++ )
      AM[i][j] = INFTY;

  for ( i = 0; i < n; i++ ) {
    scanf("%d%d", &u, &k);
    for ( j = 0; j < k; j++ ) {
      scanf("%d", &v);
      scanf("%d", &AM[u][v]);
    }
  }

  // Find the Single Source Shortest Path by Dijkstra's Algorithm
  dijkstra(0);

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

  return 0;
}