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>

#define MAX_N       10000
#define QUE_SIZE    500000

#define COST_NONE   0xFFFF


/* priority queue */
typedef struct _QueItem {
    unsigned short cost;
    unsigned short id;
} QueItem;
QueItem heapq[QUE_SIZE]; /* index 0: unuse, index 1.. : que */
int quecnt;

void enq(QueItem a);
QueItem deq();
int qcmp(QueItem a, QueItem b);


unsigned short cost[MAX_N];
unsigned short path[MAX_N][MAX_N];


int main(){
    int n,u,k,v,c;
    int i,j,tn,tk;
    int fin_cnt;
    QueItem item,item2;
    /* init */
    for(i=0;i<MAX_N;i++){
        for(j=0;j<MAX_N;j++){
            path[i][j]=COST_NONE;
        }
        cost[i]=COST_NONE;
    }
    /* input */
    scanf("%d",&n);
    for(tn=0;tn<n;tn++){
        scanf("%d %d",&u,&k);
        for(tk=0;tk<k;tk++){
            scanf("%d %d",&v,&c);
            path[u][v]=c;
        }
    }

    /* calc */
    cost[0] = 0;
    for(i=1;i<n;i++){
        if(path[0][i]!=COST_NONE){
            item.cost = path[0][i];
            item.id   = i;
            enq(item);
        }
    }

    fin_cnt = 1;
    while(fin_cnt<n){
        item = deq();
        if(cost[item.id]==COST_NONE){
            cost[item.id]=item.cost;
            fin_cnt++;
            for(i=0;i<n;i++){
                if(path[item.id][i]!=COST_NONE && cost[i]==COST_NONE){
                    item2.cost = item.cost + path[item.id][i];
                    item2.id   = i;
                    enq(item2);
                }
            }
        }
    }

    /* output */
    for(i=0;i<n;i++){
        printf("%d %d\n",i,cost[i]);
    }

    return 0;
}




/* add a to heapq */
void enq(QueItem a){
    int i;
    QueItem tmp;
    quecnt++;
    heapq[quecnt] = a;
    for(i=quecnt;i/2>0;i/=2){
        if(qcmp(heapq[i/2],heapq[i]))break;
        tmp = heapq[i];
        heapq[i] = heapq[i/2];
        heapq[i/2] = tmp;
    }
}

/* get highest priority item in heapq */
QueItem deq(){
    int i,target;
    QueItem tmp,ret;
    ret = heapq[1];
    heapq[1] = heapq[quecnt];
    quecnt--;
    for(i=1;i*2<=quecnt;){
        if( i*2+1<=quecnt && qcmp(heapq[i*2+1],heapq[i]) ){
            if( qcmp(heapq[i*2],heapq[i*2+1]) ){
                target = i*2;
            }else{
                target = i*2+1;
            }
        }else if( qcmp(heapq[i*2],heapq[i]) ){
            target = i*2;
        }else{
            break;
        }
        tmp = heapq[i];
        heapq[i] = heapq[target];
        heapq[target] = tmp;
        i = target;
    }
    return ret;
}

/* return TRUE if priority(a) > priority(b) */
int qcmp(QueItem a, QueItem b){
    return (a.cost<b.cost);
}