Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <iostream>
- #include <cassert>
- #include <climits>
- #include <vector>
- #include <queue>
- class Edge;
- class Vertex;
- using std::cout;
- using std::cin;
- using std::endl;
- using VertexVector = std::vector<Vertex *>;
- using Element = std::pair<Vertex *, int>;
- auto compare = [](const Element& lhs, const Element& rhs) {
- return lhs.second > rhs.second;
- };
- using Queue = std::priority_queue<Element, std::vector<Element>, decltype(compare)>;
- int vertices_num;
- int edges_num;
- int start_index;
- int end_index;
- int time_end;
- int shortest_trip_at_time_0 = 0;
- int shortest_trip_at_time_end = 0;
- Queue queue(compare);
- std::vector<Vertex *> vertices;
- class Edge
- {
- public:
- int destination;
- int value_at_time_0;
- int value_at_time_end;
- Edge(int a_destination, int an_initial_value, int a_change, int time_end)
- : destination(a_destination)
- , value_at_time_0(an_initial_value)
- , value_at_time_end(an_initial_value + a_change * time_end)
- {}
- };
- class Vertex
- {
- public:
- std::vector<Edge *> edges;
- int distance = INT_MAX;
- int trip_so_far = 0;
- };
- void populate_queue(VertexVector vertices, Queue& queue)
- {
- for (auto& v : vertices)
- queue.push(Element(v, v->distance));
- }
- void initialize_start_vertex(Vertex * start_vertex)
- {
- start_vertex->distance = 0;
- start_vertex->trip_so_far = 0;
- }
- void repair_vertices(std::vector<Vertex *>& vertices)
- {
- for (auto& v : vertices) {
- v->distance = INT_MAX;
- v->trip_so_far = 0;
- }
- }
- inline int get_value_at_time_0(const Edge* edge)
- {
- return edge->value_at_time_0;
- }
- inline int get_value_at_time_end(const Edge* edge)
- {
- return edge->value_at_time_end;
- }
- void run_dijkstra(Queue& queue, VertexVector& vertices, int (*get_time)(const Edge*))
- {
- while (!queue.empty()) {
- Element element = queue.top();
- queue.pop();
- Vertex * vertex = element.first;
- for (auto& edge : vertex->edges) {
- int distance = get_time(edge);
- Vertex * neighbor = vertices[edge->destination];
- if (distance < neighbor->distance) {
- neighbor->distance = distance;
- neighbor->trip_so_far = distance + vertex->trip_so_far;
- Element neighbor_element(neighbor, distance);
- queue.push(neighbor_element);
- }
- }
- }
- }
- inline int min(const int a, const int b)
- {
- return a < b ? a : b;
- }
- void handle_input()
- {
- cin >> vertices_num >> edges_num >> start_index >> end_index >> time_end;
- for (int i = 0; i < vertices_num + 1; i++) { // One extra.
- vertices.push_back(new Vertex());
- }
- int va, vb, init_val_ab, init_val_ba, change_ab, change_ba;
- for (int i = 0; i < edges_num; i++) {
- cin >> va >> vb >> init_val_ab >> change_ab >> init_val_ba >> change_ba;
- vertices[va]->edges.push_back(new Edge(vb, init_val_ab, change_ab, time_end));
- vertices[vb]->edges.push_back(new Edge(va, init_val_ba, change_ba, time_end));
- }
- }
- int main()
- {
- handle_input();
- Vertex * start_vertex = vertices[start_index];
- Vertex * end_vertex = vertices[end_index];
- // Testing time 0 from start to end.
- initialize_start_vertex(start_vertex);
- populate_queue(vertices, queue);
- run_dijkstra(queue, vertices, get_value_at_time_0);
- shortest_trip_at_time_0 = end_vertex->trip_so_far;
- // Testing time 0 from end to start.
- repair_vertices(vertices);
- initialize_start_vertex(end_vertex);
- populate_queue(vertices, queue);
- run_dijkstra(queue, vertices, get_value_at_time_0);
- shortest_trip_at_time_0 += start_vertex->trip_so_far;
- // Testing time end from start to end.
- repair_vertices(vertices);
- initialize_start_vertex(start_vertex);
- populate_queue(vertices, queue);
- run_dijkstra(queue, vertices, get_value_at_time_end);
- shortest_trip_at_time_end = end_vertex->trip_so_far;
- // Testing time end from end to start.
- repair_vertices(vertices);
- initialize_start_vertex(end_vertex);
- populate_queue(vertices, queue);
- run_dijkstra(queue, vertices, get_value_at_time_end);
- shortest_trip_at_time_end += start_vertex->trip_so_far;
- cout << min(shortest_trip_at_time_0, shortest_trip_at_time_end) << endl;
- return 0;
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement