-
Notifications
You must be signed in to change notification settings - Fork 2
/
dijkstra.cpp
73 lines (64 loc) · 1.94 KB
/
dijkstra.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
#include <stdexcept>
#include "dijkstra.h"
Dijkstra::Dijkstra(const Graph &graph)
: graph(graph)
{
}
vector <int> Dijkstra::runAlgorithm(int source)
{
int size = graph.size();
if (source >= size)
throw std::runtime_error("Error: source not in graph.");
if (graph.isNegativeEdgeWeight())
throw std::runtime_error("Error: Dijkstra algorithm - negative weights.");
vector <int> visitedDistance(size, INT_MAX);
visitedDistance[source] = 0;
const vector<int> distancesSource = graph.row(source);
map<int, int> unvistiedDistance;
for ( int i = 0 ; i < size ; i++ )
{
if ( i != source )
{
if ( distancesSource[i] == 0 )
unvistiedDistance[i] = INT_MAX;
else
unvistiedDistance[i] = distancesSource[i];
}
}
while ( !unvistiedDistance.empty() )
{
int target = minDistance(unvistiedDistance);
int targetDistance = unvistiedDistance[target];
visitedDistance[target] = targetDistance;
unvistiedDistance.erase(target);
const vector<int> dTarget = graph.row(target);
for ( auto it = unvistiedDistance.cbegin()
; it != unvistiedDistance.cend()
; it++ )
{
if ( dTarget[it->first] > 0
&& targetDistance + dTarget[it->first] < it->second )
{
unvistiedDistance[it->first]
= targetDistance + dTarget[it->first];
}
}
}
return visitedDistance;
}
int Dijkstra::minDistance(map<int, int> intMap)
{
int minValue = INT_MAX;
int minKey = INT_MAX;
for ( auto it = intMap.cbegin() ; it != intMap.cend() ; it++ )
{
if (it->second < minValue)
{
minKey = it->first;
minValue = it->second;
}
}
if (INT_MAX == minKey)
throw std::runtime_error("Error: disjoint graph.");
return minKey;
}