Advertisement
smatskevich

Seminar8

Apr 3rd, 2023
660
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 4.02 KB | None | 0 0
  1. #include <iostream>
  2. #include <queue>
  3.  
  4. #include "ListGraph.hpp"
  5. #include "SetGraph.hpp"
  6.  
  7. void DFSReverseRecursive(size_t u, const IGraph& graph,
  8.                          std::vector<bool>& visited, std::vector<size_t>& to_go) {
  9.   visited[u] = true;
  10.   for (size_t v : graph.FindAllAdjacentIn(u)) {
  11.     if (!visited[v]) DFSReverseRecursive(v, graph, visited, to_go);
  12.   }
  13.   to_go.push_back(u);
  14. }
  15.  
  16. std::vector<size_t> DFSReverse(const IGraph& graph) {
  17.   std::vector<size_t> to_go;
  18.   std::vector<bool> visited(graph.VerticesCount());
  19.   for (size_t s = 0; s < graph.VerticesCount(); ++s) {
  20.     if (!visited[s]) DFSReverseRecursive(s, graph, visited, to_go);
  21.   }
  22.   return to_go;
  23. }
  24.  
  25. void DFSCondense(size_t u, const IGraph& graph, std::vector<bool>& visited, std::vector<size_t>& component,
  26.                  size_t current_component) {
  27.   visited[u] = true;
  28.   component[u] = current_component;
  29.   for (int v : graph.FindAllAdjacentOut(u)) {
  30.     if (!visited[v])
  31.       DFSCondense(v, graph, visited, component, current_component);
  32.   }
  33. }
  34.  
  35. std::unique_ptr<IGraph> Condense(const IGraph& graph) {
  36.   // Обход по обратным ребрам для Косарайю.
  37.   std::vector<size_t> to_go = DFSReverse(graph);
  38.   // Обход по прямым ребрам Косарайю, сохранение component: v -> номер компоненты
  39.   std::vector<bool> visited(graph.VerticesCount());
  40.   size_t current_component = 0;
  41.   std::vector<size_t> component(graph.VerticesCount());
  42.   for (int i = to_go.size() - 1; i >= 0; --i) {
  43.     if (!visited[to_go[i]]) {
  44.       DFSCondense(to_go[i], graph, visited, component, current_component);
  45.       ++current_component;
  46.     }
  47.   }
  48.  
  49.   for (size_t i = 0; i < component.size(); ++i) {
  50.     std::cout << i << "->" << component[i] << ", ";
  51.   }
  52.   std::cout << std::endl;
  53.  
  54.     // Создаем граф конденсации.
  55.   std::unique_ptr<IGraph> condense = std::make_unique<SetGraph>(current_component);
  56.   // Заполняем ребра.
  57.   for (size_t u = 0; u < graph.VerticesCount(); ++u) {
  58.     for (size_t v : graph.FindAllAdjacentOut(u)) {
  59.       if (component[u] != component[v]) {
  60.         condense->AddEdge(component[u], component[v]);
  61.       }
  62.     }
  63.   }
  64.  
  65.   return condense;
  66. }
  67.  
  68. int main1() {
  69.   ListGraph lg(10);
  70.   lg.AddEdge(6, 0);
  71.   lg.AddEdge(3, 2);
  72.   lg.AddEdge(2, 1);
  73.   lg.AddEdge(2, 5);
  74.   lg.AddEdge(1, 5);
  75.   lg.AddEdge(3, 4);
  76.   lg.AddEdge(4, 7);
  77.   lg.AddEdge(7, 8);
  78.   lg.AddEdge(8, 4);
  79.   lg.AddEdge(5, 7);
  80.   lg.AddEdge(1, 9);
  81.   lg.AddEdge(9, 3);
  82.  
  83.   auto condense = Condense(lg);
  84.   std::cout << condense->VerticesCount() << std::endl;
  85.   for (size_t u = 0; u < condense->VerticesCount(); ++u) {
  86.     for (size_t v : condense->FindAllAdjacentOut(u)) {
  87.       std::cout << u << " " << v << std::endl;
  88.     }
  89.   }
  90.   return 0;
  91. }
  92.  
  93. class CompD {
  94.  public:
  95.   explicit CompD(const std::vector<int>& d) : d_(d) {}
  96.   bool operator()(int a, int b) { return d_[a] > d_[b]; }
  97.  
  98.  private:
  99.   const std::vector<int>& d_;
  100. };
  101.  
  102. std::vector<int> Dijkstra(const std::vector<std::vector<int>>& matrix, int start) {
  103.   std::vector<int> distances(matrix.size(), INT_MAX);
  104.   distances[start] = 0;
  105.   CompD comparer(distances);
  106.   std::priority_queue<int, std::vector<int>, CompD> q(comparer);
  107.   q.push(start);
  108.   while (!q.empty()) {
  109.     int u = q.top(); q.pop();
  110.     for (int v = 0; v < matrix.size(); ++v) {
  111.       int w = matrix[u][v];
  112.       if (w >= 0) {
  113.         if (distances[v] > distances[u] + w) {
  114.           q.DecreaseKey(v, distances[u] + w);
  115.           distances[v] = distances[u] + w;
  116.         }
  117.       }
  118.     }
  119.   }
  120.   return distances;
  121. }
  122.  
  123. /*
  124. 7
  125. 10
  126. 1 6 14
  127. 1 3 9
  128. 1 2 7
  129. 2 3 10
  130. 3 6 2
  131. 6 5 9
  132. 2 4 15
  133. 3 4 11
  134. 4 5 6
  135. 5 4 6
  136. */
  137.  
  138. int main() {
  139.   int n; std::cin >> n;
  140.   std::vector<std::vector<int>> matrix(n, std::vector<int>(n, -1));
  141.   int e; std::cin >> e;
  142.   for (int i = 0; i < e; ++i) {
  143.     int u, v, w; std::cin >> u >> v >> w;
  144.     matrix[u][v] = w;
  145.   }
  146.   int start; std::cin >> start;
  147.   std::vector<int> distances = Dijkstra(matrix, start);
  148.   return 0;
  149. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement