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
| #include <cstdio> #include <iostream> #include <vector> #include <list> #include <stack>
using namespace std; using Matrix = vector<vector<uint>>; using SNodes = vector<tuple<uint, uint, uint>>; using UNodes = list<tuple<uint, uint, uint>>; using ENode = tuple<uint, uint, uint>;
ENode searchNearest(const UNodes &unvisitedNodes) { uint minDistance = UINT_MAX; ENode nearest; for (const auto &node: unvisitedNodes) { if (get<1>(node) <= minDistance) { minDistance = get<1>(node); nearest = node; } } return nearest; }
SNodes dijkstra(const Matrix &graph, uint startNodeIndex) { const uint numOfNodes = graph.size(); SNodes visitedNodes; UNodes unvisitedNodes;
for (auto i = 0; i < numOfNodes; ++i) { if (i == startNodeIndex) visitedNodes.emplace_back(i, 0, startNodeIndex); else unvisitedNodes.emplace_back(i, graph[startNodeIndex][i], startNodeIndex); }
while (!unvisitedNodes.empty()) { auto nextNode = searchNearest(unvisitedNodes); unvisitedNodes.erase(find(unvisitedNodes.begin(), unvisitedNodes.end(), nextNode)); visitedNodes.emplace_back(nextNode); for (auto &node: unvisitedNodes) { if (graph[get<0>(nextNode)][get<0>(node)] != UINT_MAX && graph[get<0>(nextNode)][get<0>(node)] + get<1>(nextNode) < get<1>(node)) { get<1>(node) = graph[get<0>(nextNode)][get<0>(node)] + get<1>(nextNode); get<2>(node) = get<0>(nextNode); } } }
return visitedNodes; }
void print(const SNodes &paths) { stack<int> tracks; for (auto it = ++paths.begin(); it != paths.end(); ++it) { printf("%c -> %c:\t Length: %d\t Paths: %c", char(get<0>(paths[0]) + 65), char(get<0>(*it) + 65), get<1>(*it), char(get<0>(paths[0]) + 65)); auto pointer = *it; while (get<2>(pointer) != get<0>(paths[0])) { tracks.push(get<0>(pointer)); auto condition = [pointer](tuple<uint, uint, uint> x) { return get<0>(x) == get<2>(pointer); }; pointer = *find_if(paths.begin(), paths.end(), condition); } tracks.push(get<0>(pointer));
while (!tracks.empty()) { printf(" -> %c", char(tracks.top() + 65)); tracks.pop(); } printf("\n"); } }
int main() { Matrix graph = { {0, 12, UINT_MAX, UINT_MAX, UINT_MAX, 16, 14}, {12, 0, 10, UINT_MAX, UINT_MAX, 7, UINT_MAX}, {UINT_MAX, 10, 0, 3, 5, 6, UINT_MAX}, {UINT_MAX, UINT_MAX, 3, 0, 4, UINT_MAX, UINT_MAX}, {UINT_MAX, UINT_MAX, 5, 4, 0, 2, 8}, {16, 7, 6, UINT_MAX, 2, 9, 9}, {14, UINT_MAX, UINT_MAX, UINT_MAX, 8, 9, 0} }; auto results = dijkstra(graph, uint('D' - 65)); print(results); return 0; }
|