Advertisement
Guest User

Untitled

a guest
Oct 17th, 2019
111
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 4.58 KB | None | 0 0
  1. #include <algorithm>
  2. #include <climits>
  3. #include <functional>
  4. #include <iostream>
  5. #include <set>
  6. #include <queue>
  7. #include <vector>
  8. #include <unordered_map>
  9.  
  10. struct Vertex {
  11. public:
  12.     int number, path_length;
  13.  
  14.     Vertex(){};
  15.  
  16.     Vertex(int v, int p) {
  17.         number = v;
  18.         path_length = p;
  19.     }
  20.  
  21.     bool operator<(const Vertex &other) const {
  22.         return path_length < other.path_length;
  23.     }
  24. };
  25.  
  26. class Graph {
  27. private:
  28.     int vertices_number, source, target;
  29.     std::unordered_map<int, std::unordered_map<int, int>> forward_graph;
  30.     std::unordered_map<int, std::unordered_map<int, int>> backward_graph;
  31.  
  32. public:
  33.     bool path_exists = false;
  34.  
  35.     Graph() {};
  36.  
  37.     Graph(int n) {
  38.         vertices_number = n;
  39.     }
  40.  
  41.     void init_s_t(int s, int t) {
  42.         source = s;
  43.         target = t;
  44.     }
  45.  
  46.     void add_edge(int from, int to, int weight) {
  47.         forward_graph[from][to] = weight;
  48.         backward_graph[to][from] = weight;
  49.     }
  50.  
  51.     std::vector<uint> dijkstra(bool forward, int d) {
  52.         std::vector<uint> dist(vertices_number, UINT_MAX);
  53.         std::vector<bool> closed(vertices_number, false);
  54.         std::set<Vertex> vertices_to_add;
  55.  
  56.         (forward ? dist[source] = 0 : dist[target] = 0);
  57.  
  58.         (forward ? vertices_to_add.insert(Vertex(source, 0)) : vertices_to_add.insert(Vertex(target, 0)));
  59.  
  60.         for (size_t i = 0; i != vertices_number; ++i) {
  61.             // pick new vertex
  62.             if (vertices_to_add.empty()) break;
  63.  
  64.             Vertex shortest_vertex = *vertices_to_add.begin();
  65.             vertices_to_add.erase(vertices_to_add.begin());
  66.  
  67.             if (forward && shortest_vertex.number == target) {
  68.                 path_exists = true;
  69.                 break;
  70.             }
  71.  
  72.             closed[shortest_vertex.number] = true;
  73.  
  74.             if (dist[shortest_vertex.number] >= d) break;
  75.  
  76.             // update new neighbours values
  77.             for (auto neighbour : (forward ? forward_graph[shortest_vertex.number] : backward_graph[shortest_vertex.number])) {
  78.                 // neighbour - map element: neighbour.first = vertex_number, neighbour.second = edge_weight
  79.                 if (!closed[neighbour.first]) {
  80.                     // std::cout << "Processing neighbour " << neighbour.first << std::endl;
  81.                     if ((dist[shortest_vertex.number] + neighbour.second < dist[neighbour.first]) && (dist[neighbour.first] != UINT_MAX)) {
  82.                         vertices_to_add.erase(Vertex(neighbour.first, dist[neighbour.first]));
  83.                     }
  84.  
  85.                     dist[neighbour.first] = dist[shortest_vertex.number] + neighbour.second;
  86.                     vertices_to_add.insert(Vertex(neighbour.first, dist[neighbour.first]));
  87.                 }
  88.             }        }
  89.         return dist;
  90.     }
  91. };
  92.  
  93. int main () {
  94.     int n, m, from, to, weight, s, t, d;
  95.     long long res = 0;
  96.  
  97.     std::cin >> n >> m;
  98.  
  99.     Graph graph(n);
  100.  
  101.     for (size_t i = 0; i < m; ++i) {
  102.         std::cin >> from >> to >> weight;
  103.         graph.add_edge(from - 1, to - 1, weight);
  104.     }
  105.  
  106.     std::cin >> s >> t >> d;
  107.     graph.init_s_t(s - 1, t - 1);
  108.  
  109.     std::vector<uint> forward_candidates;
  110.     forward_candidates = graph.dijkstra(true, d);
  111.  
  112.     if  (graph.path_exists) {
  113.         std::cout << n * (n - 1) << std::endl;
  114.         return 0;
  115.     }
  116.  
  117.     std::vector<uint> backward_candidates;
  118.     backward_candidates = graph.dijkstra(false, d);
  119.  
  120.  
  121.     // int art = 0;
  122.     // for (size_t i = 0; i != forward_candidates.size(); ++i) {
  123.     //     std::cout << forward_candidates[i] << ' ';
  124.     //     if (forward_candidates[i] <= d - 1) {
  125.     //         // art++;
  126.     //     }
  127.     // }
  128.  
  129.     // // std::cout << std::endl << "art: " << art << std::endl;
  130.  
  131.     // // int cnt = 0;
  132.     // for (size_t i = 0; i != backward_candidates.size(); ++i) {
  133.     //     std::cout << backward_candidates[i] << ' ';
  134.     //     if (backward_candidates[i] <= d - 1) {
  135.     //         // cnt++;
  136.     //     }
  137.     // }
  138.  
  139.     // std::cout << std::endl << "cnt: " << cnt << std::endl;
  140.  
  141.     for (size_t i = 0; i != forward_candidates.size(); ++i) {
  142.         for (size_t j = 0; j != backward_candidates.size(); ++j) {
  143.             if (forward_candidates[i] == UINT_MAX || backward_candidates[j] == UINT_MAX) {
  144.                 continue;
  145.             }
  146.  
  147.             if (forward_candidates[i] + backward_candidates[j] + 1 <= d) {
  148.                 // std::cout << i << ' ' << j << std::endl;
  149.                 res++;
  150.             }
  151.         }
  152.     }
  153.  
  154.     std::cout << res << std::endl;
  155. }
  156. close
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement