#include <inttypes.h>
#include <limits>
#include "rheap/rheap.h"

using rheap::rheap_t;

void dijkstra(double* d, double* p, size_t* jc, size_t* ir, double* cost, int64_t src, int64_t n) {
	ASSERT(n > 0, "Graph should be non-empty.");
    
    static const double inf = 1. / 0.;
    
	double maxcost = cost[0];
	for(int64_t i = 1; i < n; ++i)
		if(cost[i] > maxcost)
			maxcost = cost[i];
	ASSERT(maxcost < inf, "Costs must be finite.");

	for(int64_t i = 0; i < n; ++i) {
		d[i] = inf;
		p[i] = -1;
	}

	rheap_t heap(n, (uint64_t)maxcost);
    d[src] = 0;
	heap.insert(src, 0);
    while(!heap.is_empty()) {
		uint64_t u = heap.delete_min();
		double du = d[u];
        for(uint64_t i = jc[u]; i < jc[u + 1]; ++i) {
            int64_t v = ir[i];
            double alt_route_cost = du + cost[i];
            if(d[v] > alt_route_cost) {
                d[v] = alt_route_cost;
				p[v] = u + 1;
				if(heap.contains(v))
					heap.decrease_key(v, (int64_t)d[v]);
				else
					heap.insert(v, (int64_t)d[v]);
            }
        }
    }
}
