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>
#include<limits.h>

#define WHITE -1
#define  GRAY  0
#define BRACK  1

typedef struct{
  int key;
  int d;
} edge;

typedef struct{
  int k;
  char color;
  int d;
  edge *A;
} Point;

void heapIN(int,edge);
void insert(int, int);
edge extract(void);
void Mheap(int);

int H=0;
edge *Q;

int main(){
  Point *p;
  edge mind;
  int i,j,n,v,u,id,qsize=0;

  scanf("%d",&n);
  p=(Point *)malloc(sizeof(Point)*n);

  for(i=0;i<n;i++){
    //   printf("test1\n");
      
    scanf("%d%d",&id,&p[i].k);
    
    p[i].A=(edge *)malloc(sizeof(edge)*p[i].k);
    qsize+=p[i].k;

    //printf("==%d\n",sizeof(edge));

    for(j=0;j<p[i].k;j++){
      scanf("%d%d",&p[i].A[j].key,&p[i].A[j].d);
      //printf("A=%d C=%d\n",p[i].A[j].key,p[i].A[j].d);
    }

    p[i].color=WHITE;
    p[i].d=INT_MAX;
  }

  Q=(edge *)malloc(sizeof(edge)*qsize);
    
  p[0].d=0;
  insert(0,0);

  while(H != 0){
    mind = extract();
    u=mind.key;

    //printf("u=%d\n",u);
    p[u].color = BRACK;
    if(p[u].d < mind.d) continue;
    
    for(i=0;i<p[u].k;i++){
      v = p[u].A[i].key;
;
      if(p[v].color != BRACK && p[u].d + p[u].A[i].d < p[v].d){
	//printf("v=%d,p[u].A[v].key=%d \n",v,p[u].A[i].key);
	p[v].d = p[u].d + p[u].A[i].d;
	p[v].color=GRAY;
	insert(v,p[v].d);
      }
    }
  }

  for(i=0;i<n;i++){
    printf("%d %d\n",i,p[i].d == INT_MAX ? -1 : p[i].d);
    //printf("color[%d]=%d\n",i,p[i].color);
  }

  return 0;
}

void insert(int key, int d){
  edge in;

  //printf("key=%d,d=%d ",key,d);

  in.key=key;
  in.d=d;
  
  H++;
  Q[H].d=INT_MAX;
  heapIN(H,in);
}

void heapIN(int i,edge in){
    edge swap;

    //printf("in.d=%d ",in.d);
    
    if (in.d>Q[i].d) return;
    Q[i]=in;

    //for(i=0;i<=H;i++){ printf("insert Q[%d].key=%d,Q[%d].d=%d  ",i,Q[i].key,i,Q[i].d);} printf("\n");
    
    while(i>1 && Q[i/2].d > Q[i].d){
        swap=Q[i/2];
        Q[i/2]=Q[i];
        Q[i]=swap;
        i/=2;
    }
    //for(i=0;i<=H;i++){ printf("insert H=%d,Q[%d].key=%d,Q[%d].d=%d  ",H,i,Q[i].key,i,Q[i].d);} printf("\n");
}

edge extract(){
    edge min;
    int i;
    
    if(H<1) return Q[0];
    min=Q[1];
    Q[1]=Q[H];
    H--;
    Mheap(1);
    //for(i=0;i<=H;i++) printf("extract Q[%d]=%d ",i,Q[i].key); printf("\n");
   
    return min;
}

void Mheap(int i){
    int l,r,small;
    edge swap;
    
    l = i*2;
    r = i*2+1;
    
    if(l <= H && Q[l].d < Q[i].d) small = l;
    else small=i;
    if(r <= H && Q[r].d < Q[small].d) small = r;
    
    if(small != i){
        swap=Q[small];
        Q[small]=Q[i];
        Q[i]=swap;
        
        Mheap(small);
    }
}