#ifndef __DIJKSTRAASSSP_H
#define __DIJKSTRAASSSP_H
#include <vector>
#include <cmath>
using namespace std;

#include "BinaryHeap.h"
typedef int vertex;

struct Edgenode {
	Vertex w;
	double weight; // length of edge to w from owner of edgenode list.
	Edgenode *next;
};

struct graph {
	vector<Edgenode*> nbr;
};

typedef double Distance;
const Distance INFINITY = DBL_MAX*DBL_MAX;

//struct lt { bool operator()(Distance a, Distance b) { return a < b; }

// Single source shortest paths
void Dijkstra(	
		const graph G, //the graph
		Vertex s ) // the source node 
{
	int n = G.nbr.size(); // number of vertices.
	vector<Distance> dist(n);
	vector<Vertex> parent(n);
	for (Vertex u = 0; u < n; ++u) {
		dist[u] = INFINITY; parent[u]=u; //i.e. no path to s yet. 
	}
	dist[s] = 0;

	//H = makequeue(V)
	Heap<Distance> H( dist );
	for (Vertex u = 0; u < n; ++u) H.insert( u );

	while ( ! H.isEmpty() ) {
		Vertex v = H.extractMin();
		for (Edgenode *p  = G.nbr[v]; p != NULL; p = p->next) {
			Vertex u = p->w;
			Distance d = p->weight;
			if (dist[u] > dist[v] + d) {
				parent[u] = v;
				dist[u] = dist[v] + d;
				H.decreaseKey(u);
			}
		}
	}
};
#endif // __DIJKSTRAASSSP_H
