kopia lustrzana https://github.com/jameshball/osci-render
71 wiersze
1.5 KiB
C++
71 wiersze
1.5 KiB
C++
#pragma once
|
|
|
|
#include "./Graph.h"
|
|
#include "./BinaryHeap.h"
|
|
#include "./Globals.h"
|
|
#include <limits>
|
|
using namespace std;
|
|
|
|
//Dijkstra's algorithm using binary heap
|
|
//Returns a pair (vector<int>, vector<double>)
|
|
//vector<double> gives the cost of the optimal path to each vertex
|
|
//vector<int> gives the parent of each vertex in the tree of optimal paths
|
|
pair< vector<int>, vector<double> > Dijkstra(Graph & G, int origin, vector<double> & cost)
|
|
{
|
|
BinaryHeap B;
|
|
|
|
int n = G.GetNumVertices();
|
|
|
|
//Father of each vertex in the optimal path tree
|
|
vector<int> father(n, -1);
|
|
|
|
//Used to indicate whether a vertex is permanently labeled
|
|
vector<bool> permanent(n, false);
|
|
|
|
vector<double> pathCost(n, numeric_limits<double>::infinity());
|
|
|
|
//Put s in the heap
|
|
B.Insert(0, origin);
|
|
pathCost[origin] = 0;
|
|
|
|
for(int i = 0; i < n; i++)
|
|
{
|
|
//Select the vertex that can be reached with smallest cost
|
|
int u = B.DeleteMin();
|
|
|
|
permanent[u] = true;
|
|
|
|
//Update the heap with vertices adjacent to u
|
|
for (int v : G.AdjList(u)) {
|
|
|
|
if(permanent[v])
|
|
continue;
|
|
|
|
double c = pathCost[u] + (cost.empty() ? 1.0 : cost[G.GetEdgeIndex(u,v)]);
|
|
|
|
//v has not been discovered yet
|
|
if(father[v] == -1)
|
|
{
|
|
father[v] = u;
|
|
pathCost[v] = c;
|
|
B.Insert(c, v);
|
|
}
|
|
//we found a cheaper connection to v
|
|
else if( LESS(c, pathCost[v]) )
|
|
{
|
|
father[v] = u;
|
|
pathCost[v] = c;
|
|
B.ChangeKey(c, v);
|
|
}
|
|
}
|
|
}
|
|
|
|
if(B.Size() > 0)
|
|
throw "Error: graph is not connected";
|
|
|
|
return make_pair(father, pathCost);
|
|
}
|
|
|
|
|
|
|