-
Notifications
You must be signed in to change notification settings - Fork 11
/
DijkstraShortestPath.cpp
156 lines (130 loc) · 3.81 KB
/
DijkstraShortestPath.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
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
//Purpose: Implementation of Dijkstra's algorithm which finds the shortest
//path from a start node to every other node in a weighted graph.
//Time complexity: O(n^2)
#include <iostream>
#include <limits>
using namespace std;
#define MAXV 1000
class EdgeNode{
public:
int key;
int weight;
EdgeNode *next;
EdgeNode(int, int);
};
EdgeNode::EdgeNode(int key, int weight){
this->key = key;
this->weight = weight;
this->next = NULL;
}
class Graph{
bool directed;
public:
EdgeNode *edges[MAXV + 1];
Graph(bool);
~Graph();
void insert_edge(int, int, int, bool);
void print();
};
Graph::Graph(bool directed){
this->directed = directed;
for(int i = 1; i < (MAXV + 1); i ++){
this->edges[i] = NULL;
}
}
Graph::~Graph(){
//to do
}
void Graph::insert_edge(int x, int y, int weight, bool directed){
if(x > 0 && x < (MAXV + 1) && y > 0 && y < (MAXV + 1)){
EdgeNode *edge = new EdgeNode(y, weight);
edge->next = this->edges[x];
this->edges[x] = edge;
if(!directed){
insert_edge(y, x, weight, true);
}
}
}
void Graph::print(){
for(int v = 1; v < (MAXV + 1); v ++){
if(this->edges[v] != NULL){
cout << "Vertex " << v << " has neighbors: " << endl;
EdgeNode *curr = this->edges[v];
while(curr != NULL){
cout << curr->key << endl;
curr = curr->next;
}
}
}
}
void init_vars(bool discovered[], int distance[], int parent[]){
for(int i = 1; i < (MAXV + 1); i ++){
discovered[i] = false;
distance[i] = std::numeric_limits<int>::max();
parent[i] = -1;
}
}
void dijkstra_shortest_path(Graph *g, int parent[], int distance[], int start){
bool discovered[MAXV + 1];
EdgeNode *curr;
int v_curr;
int v_neighbor;
int weight;
int smallest_dist;
init_vars(discovered, distance, parent);
distance[start] = 0;
v_curr = start;
while(discovered[v_curr] == false){
discovered[v_curr] = true;
curr = g->edges[v_curr];
while(curr != NULL){
v_neighbor = curr->key;
weight = curr->weight;
if((distance[v_curr] + weight) < distance[v_neighbor]){
distance[v_neighbor] = distance[v_curr] + weight;
parent[v_neighbor] = v_curr;
}
curr = curr->next;
}
//set the next current vertex to the vertex with the smallest distance
smallest_dist = std::numeric_limits<int>::max();
for(int i = 1; i < (MAXV + 1); i ++){
if(!discovered[i] && (distance[i] < smallest_dist)){
v_curr = i;
smallest_dist = distance[i];
}
}
}
}
void print_shortest_path(int v, int parent[]){
if(v > 0 && v < (MAXV + 1) && parent[v] != -1){
cout << parent[v] << " ";
print_shortest_path(parent[v], parent);
}
}
void print_distances(int start, int distance[]){
for(int i = 1; i < (MAXV + 1); i ++){
if(distance[i] != std::numeric_limits<int>::max()){
cout << "Shortest distance from " << start << " to " << i << " is: " << distance[i] << endl;
}
}
}
int main(){
Graph *g = new Graph(false);
int parent[MAXV + 1];
int distance[MAXV + 1];
int start = 1;
g->insert_edge(1, 2, 4, false);
g->insert_edge(1, 3, 1, false);
g->insert_edge(3, 2, 1, false);
g->insert_edge(3, 4, 5, false);
g->insert_edge(2, 4, 3, false);
g->insert_edge(2, 5, 1, false);
g->insert_edge(4, 5, 2, false);
dijkstra_shortest_path(g, parent, distance, start);
//print shortest path from vertex 1 to 5
print_shortest_path(5, parent);
print_distances(start, distance);
delete g;
return 0;
}