dan_sml

Sem_2_Task_2

Apr 30th, 2022
913
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 3.51 KB | None | 0 0
  1. #include <iostream>
  2. #include <vector>
  3. #include <algorithm>
  4. #include <set>
  5.  
  6. struct Edge;
  7.  
  8. const size_t INF = size_t(1e12);
  9.  
  10. namespace {
  11.     using NumsVec = std::vector<size_t>;
  12.     using VecNumsVec = std::vector<NumsVec>;
  13.     using BoolVec = std::vector<bool>;
  14.     using EdgeVec = std::vector<Edge>;
  15. }
  16.  
  17. struct Edge {
  18.     Edge() = default;
  19.     Edge(std::pair<size_t, size_t> edge) : from(edge.first), to(edge.second) {};
  20.     Edge(size_t i, size_t j, size_t w) : from(i), to(j), w(w) {};
  21.  
  22.     bool operator==(const Edge& other) const {
  23.         return from == other.from && to == other.to;
  24.     }
  25.  
  26.     Edge Reverse() const {
  27.         return {to, from, w};
  28.     }
  29.  
  30.     size_t from = 0;
  31.     size_t to = 0;
  32.     size_t w = 0;
  33. };
  34.  
  35. std::istream& operator>>(std::istream& input, Edge& edge) {
  36.     input >> edge.from >> edge.to >> edge.w;
  37.     --edge.from;
  38.     --edge.to;
  39.     return input;
  40. }
  41.  
  42. void InputEdges(std::vector<Edge>& edges) {
  43.     for (auto& edge : edges) {
  44.         std::cin >> edge;
  45.     }
  46. }
  47.  
  48. template<>
  49. struct std::hash<Edge> {
  50.     size_t operator()(const Edge& p) const {
  51.         return p.from * p.to;
  52.     }
  53. };
  54.  
  55. std::ostream& operator<<(std::ostream& output, NumsVec& vec) {
  56.     for (auto elem : vec) {
  57.         std::cout << elem + 1 << " ";
  58.     }
  59.     return output;
  60. }
  61.  
  62. struct Graph {
  63.     Graph(size_t n) : size(n), neighbours(n), visited(n, false), color(n, 0),
  64.     top_sort(n, 0), top_sort_pos(n - 1), d(n, INF) {};
  65.  
  66.     Graph(size_t n, EdgeVec& edges) : size(n), neighbours(n), visited(n, false), color(n, 0),
  67.     top_sort(n, 0), top_sort_pos(n - 1), d(n, INF), p(n, INF) {
  68.         for (auto edge : edges) {
  69.             neighbours[edge.from].push_back(edge);
  70.             neighbours[edge.to].push_back(edge.Reverse());
  71.         }
  72.     };
  73.     size_t size = 0;
  74.     bool cycle = false;
  75.  
  76.     std::vector<EdgeVec> neighbours;
  77.     BoolVec visited;
  78.     NumsVec color;
  79.     NumsVec top_sort;
  80.     NumsVec d;
  81.     NumsVec p;
  82.     size_t top_sort_pos = 0;
  83. };
  84.  
  85. std::pair<size_t, size_t> Dijkstra(Graph& g, NumsVec s, NumsVec f) {
  86.     std::set<std::pair<size_t, size_t>> vert;
  87.     for (auto v : s) {
  88.         g.d[v] = 0;
  89.         vert.insert({g.d[v], v});
  90.     }
  91.     while (!vert.empty()) {
  92.         size_t v = vert.begin()->second;
  93.         vert.erase(vert.begin());
  94.         for (auto edge : g.neighbours[v]) {
  95.             if (g.d[edge.to] > g.d[v] + edge.w) {
  96.                 vert.erase({g.d[edge.to], edge.to});
  97.                 g.d[edge.to] = g.d[v] + edge.w;
  98.                 g.p[edge.to] = v;
  99.                 vert.insert({g.d[edge.to], edge.to});
  100.             }
  101.         }
  102.     }
  103.     size_t ans = INF;
  104.     size_t v_ans = 0;
  105.     for (size_t v : f) {
  106.         if (ans > g.d[v]) {
  107.             ans = g.d[v];
  108.             v_ans = v;
  109.         }
  110.     }
  111.     return {ans, v_ans};
  112. }
  113.  
  114. size_t FindParent(Graph& g, size_t v) {
  115.     while (g.p[v] != INF) {
  116.         v = g.p[v];
  117.     }
  118.     return v;
  119. }
  120.  
  121. int main() {
  122.     size_t n;
  123.     size_t m;
  124.     std::cin >> n >> m;
  125.     NumsVec cities_a;
  126.     NumsVec cities_b;
  127.     for (size_t v = 0; v < n; ++v) {
  128.         size_t city;
  129.         std::cin >> city;
  130.         if (city == 1) {
  131.             cities_a.push_back(v);
  132.         } else if (city == 2) {
  133.             cities_b.push_back(v);
  134.         }
  135.     }
  136.     EdgeVec edges(m);
  137.     InputEdges(edges);
  138.     Graph g(n, edges);
  139.     auto [ans, v] = Dijkstra(g, cities_a, cities_b);
  140.     if (ans == INF) {
  141.         std::cout << -1;
  142.     } else {
  143.         std::cout << FindParent(g, v) + 1 << " " << v + 1 << " " << ans;
  144.     }
  145. }
  146.  
Advertisement
Add Comment
Please, Sign In to add comment