Advertisement
Guest User

dijkstra

a guest
Feb 14th, 2016
64
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 4.35 KB | None | 0 0
  1. #include <iostream>
  2. #include <cassert>
  3. #include <climits>
  4. #include <vector>
  5. #include <queue>
  6.  
  7. class Edge;
  8. class Vertex;
  9.  
  10. using std::cout;
  11. using std::cin;
  12. using std::endl;
  13. using VertexVector = std::vector<Vertex *>;
  14. using Element = std::pair<Vertex *, int>;
  15. auto compare = [](const Element& lhs, const Element& rhs) {
  16.     return lhs.second > rhs.second;
  17. };
  18. using Queue = std::priority_queue<Element, std::vector<Element>, decltype(compare)>;
  19.  
  20. int vertices_num;
  21. int edges_num;
  22. int start_index;
  23. int end_index;
  24. int time_end;
  25. int shortest_trip_at_time_0 = 0;
  26. int shortest_trip_at_time_end = 0;
  27. Queue queue(compare);
  28. std::vector<Vertex *> vertices;
  29.  
  30. class Edge
  31. {
  32.     public:
  33.     int destination;
  34.     int value_at_time_0;
  35.     int value_at_time_end;
  36.  
  37.     Edge(int a_destination, int an_initial_value, int a_change, int time_end)
  38.         : destination(a_destination)
  39.         , value_at_time_0(an_initial_value)
  40.         , value_at_time_end(an_initial_value + a_change * time_end)
  41.     {}
  42. };
  43.  
  44. class Vertex
  45. {
  46.     public:
  47.     std::vector<Edge *> edges;
  48.     int distance = INT_MAX;
  49.     int trip_so_far = 0;
  50. };
  51.  
  52.  
  53. void populate_queue(VertexVector vertices, Queue& queue)
  54. {
  55.     for (auto& v : vertices)
  56.         queue.push(Element(v, v->distance));
  57. }
  58.  
  59. void initialize_start_vertex(Vertex * start_vertex)
  60. {
  61.     start_vertex->distance = 0;
  62.     start_vertex->trip_so_far = 0;
  63. }
  64.  
  65. void repair_vertices(std::vector<Vertex *>& vertices)
  66. {
  67.     for (auto& v : vertices) {
  68.         v->distance = INT_MAX;
  69.         v->trip_so_far = 0;
  70.     }
  71. }
  72.  
  73. inline int get_value_at_time_0(const Edge* edge)
  74. {
  75.     return edge->value_at_time_0;
  76. }
  77.  
  78. inline int get_value_at_time_end(const Edge* edge)
  79. {
  80.     return edge->value_at_time_end;
  81. }
  82.  
  83. void run_dijkstra(Queue& queue, VertexVector& vertices, int (*get_time)(const Edge*))
  84. {
  85.     while (!queue.empty()) {
  86.         Element element = queue.top();
  87.         queue.pop();
  88.         Vertex * vertex = element.first;
  89.  
  90.         for (auto& edge : vertex->edges) {
  91.             int distance = get_time(edge);
  92.             Vertex * neighbor = vertices[edge->destination];
  93.  
  94.             if (distance < neighbor->distance) {
  95.                 neighbor->distance = distance;
  96.                 neighbor->trip_so_far = distance + vertex->trip_so_far;
  97.                 Element neighbor_element(neighbor, distance);
  98.                 queue.push(neighbor_element);
  99.             }
  100.         }
  101.     }
  102. }
  103.  
  104. inline int min(const int a, const int b)
  105. {
  106.     return a < b ? a : b;
  107. }
  108.  
  109. void handle_input()
  110. {
  111.     cin >> vertices_num >> edges_num >> start_index >> end_index >> time_end;
  112.  
  113.     for (int i = 0; i < vertices_num + 1; i++) { // One extra.
  114.         vertices.push_back(new Vertex());
  115.     }
  116.  
  117.     int va, vb, init_val_ab, init_val_ba, change_ab, change_ba;
  118.     for (int i = 0; i < edges_num; i++) {
  119.         cin >> va >> vb >> init_val_ab >> change_ab >> init_val_ba >> change_ba;
  120.         vertices[va]->edges.push_back(new Edge(vb, init_val_ab, change_ab, time_end));
  121.         vertices[vb]->edges.push_back(new Edge(va, init_val_ba, change_ba, time_end));
  122.     }
  123. }
  124.  
  125. int main()
  126. {
  127.     handle_input();
  128.  
  129.     Vertex * start_vertex = vertices[start_index];
  130.     Vertex * end_vertex = vertices[end_index];
  131.  
  132.     // Testing time 0 from start to end.
  133.     initialize_start_vertex(start_vertex);
  134.     populate_queue(vertices, queue);
  135.     run_dijkstra(queue, vertices, get_value_at_time_0);
  136.     shortest_trip_at_time_0 = end_vertex->trip_so_far;
  137.  
  138.     // Testing time 0 from end to start.
  139.     repair_vertices(vertices);
  140.     initialize_start_vertex(end_vertex);
  141.     populate_queue(vertices, queue);
  142.     run_dijkstra(queue, vertices, get_value_at_time_0);
  143.     shortest_trip_at_time_0 += start_vertex->trip_so_far;
  144.  
  145.     // Testing time end from start to end.
  146.     repair_vertices(vertices);
  147.     initialize_start_vertex(start_vertex);
  148.     populate_queue(vertices, queue);
  149.     run_dijkstra(queue, vertices, get_value_at_time_end);
  150.     shortest_trip_at_time_end = end_vertex->trip_so_far;
  151.  
  152.     // Testing time end from end to start.
  153.     repair_vertices(vertices);
  154.     initialize_start_vertex(end_vertex);
  155.     populate_queue(vertices, queue);
  156.     run_dijkstra(queue, vertices, get_value_at_time_end);
  157.     shortest_trip_at_time_end += start_vertex->trip_so_far;
  158.  
  159.     cout << min(shortest_trip_at_time_0, shortest_trip_at_time_end) << endl;
  160.  
  161.     return 0;
  162. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement