Advertisement
Guest User

Untitled

a guest
Oct 18th, 2019
109
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 4.14 KB | None | 0 0
  1. #include <iostream>
  2. #include <queue>
  3. #include <tuple>
  4. #include <vector>
  5. #include <unordered_set>
  6. #include <unordered_map>
  7. #include <type_traits>
  8. #include <limits>
  9.  
  10. using std::pair;
  11. using std::string;
  12. using std::unordered_map;
  13. using std::unordered_set;
  14. using std::vector;
  15. using std::cout;
  16. using std::endl;
  17. using std::priority_queue;
  18.  
  19. template <typename T, typename W,
  20. typename std::enable_if<std::is_arithmetic<W>::value, W>::type* = nullptr>
  21. struct QueueElem {
  22.  
  23. QueueElem(const T& element, const W& weight)
  24. : element(element), weight(weight)
  25. {
  26. }
  27.  
  28. QueueElem() = default;
  29. ~QueueElem() = default;
  30. QueueElem(const QueueElem& other) = default;
  31. QueueElem& operator=(const QueueElem& other) = default;
  32. QueueElem(QueueElem&& other) = default;
  33. QueueElem& operator=(QueueElem&& other) = default;
  34.  
  35. T element;
  36. W weight;
  37.  
  38. bool operator<(const QueueElem& other) const {
  39. // switch signs because we need a min-priority queue
  40. return weight > other.weight;
  41. }
  42. };
  43.  
  44. template <typename T, typename W,
  45. typename std::enable_if<std::is_arithmetic<W>::value, W>::type* = nullptr>
  46. class Graph {
  47.  
  48. public:
  49.  
  50. void insertEdge(const T& from, const T& to, const W& weight = 0.0) {
  51.  
  52. insertNode(from);
  53. insertNode(to);
  54. auto found = adj.find(from);
  55. if (found != adj.end()) {
  56. found->second.emplace(to, weight);
  57. }
  58. }
  59.  
  60. std::pair<W, std::vector<T>> dijkstra(const T& from, const T& to) {
  61.  
  62. unordered_map<T, W> distances;
  63. unordered_map<T, T> previous;
  64.  
  65. for (const auto& kv : adj) {
  66. distances.emplace(kv.first, std::numeric_limits<W>::max());
  67. }
  68. distances[from] = 0;
  69.  
  70. priority_queue<QueueElem<T, W>> pq;
  71. pq.emplace(QueueElem<T, W>(from, 0));
  72. while (!pq.empty()) {
  73. auto current = pq.top();
  74. if (current.element == to) {
  75. std::vector<T> path;
  76.  
  77. T current = to;
  78. while (current != from) {
  79. path.insert(path.begin(), current);
  80. current = previous[current];
  81. }
  82. path.insert(path.begin(), from);
  83.  
  84. return {distances[to], path};
  85. }
  86. pq.pop();
  87. for (const auto& kv : adj[current.element]) {
  88. auto dst = kv.first;
  89. auto cost = kv.second;
  90. auto estimate = current.weight + adj[current.element][dst];
  91. auto curr_dist = distances[kv.first];
  92. if (estimate < curr_dist) {
  93. distances[dst] = estimate;
  94. pq.emplace(QueueElem<T, W>(dst, estimate));
  95. previous[dst] = current.element;
  96. }
  97. }
  98.  
  99. }
  100. }
  101.  
  102. void printGraph() const {
  103. std::cout << "\n[\n";
  104. for (const auto& kv : adj) {
  105. std::cout << " " << kv.first << " -> [ ";
  106. for (const auto& kv2 : kv.second) {
  107. std::cout << "(" << kv2.first << ", " << kv2.second << ") ";
  108. }
  109. std::cout << "]\n";
  110. }
  111. std::cout << "]\n" << std::endl;
  112. }
  113.  
  114.  
  115. private:
  116. std::unordered_map<T, unordered_map<T, W>> adj;
  117.  
  118. void insertNode(const T& node) {
  119. if (adj.find(node) == adj.end()) {
  120. adj.emplace(node, unordered_map<string, W>());
  121. }
  122. }
  123.  
  124.  
  125.  
  126. };
  127.  
  128. int main() {
  129.  
  130. Graph<string, int> g;
  131. g.insertEdge("Ajo", "Bordo", 50);
  132. g.insertEdge("Ajo", "Danza", 80);
  133. g.insertEdge("Bordo", "Danza", 90);
  134. g.insertEdge("Bordo", "Colina", 60);
  135. g.insertEdge("Danza", "Erizo", 70);
  136. g.insertEdge("Colina", "Erizo", 40);
  137. g.insertEdge("Danza", "Colina", 20);
  138. g.insertEdge("Erizo", "Bordo", 50);
  139.  
  140. cout << "Graph";
  141. g.printGraph();
  142.  
  143. cout << "Ajo -> Erizo: " << endl;
  144. cout << "Expected distance: 140" << endl;
  145. cout << "Epected path: Ajo -> Danza -> Colina -> Erizo" << endl;
  146. auto [shortest, path] = g.dijkstra("Ajo", "Erizo");
  147. cout << "\n\nResults:\n\n";
  148. cout << "shortest distance: " << shortest << endl;
  149. cout << "path: ";
  150. for (const auto& elem : path) {
  151. cout << elem << " ";
  152. }
  153. cout << endl;
  154.  
  155. return 0;
  156. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement