Advertisement
coloriot

HA33_SCC(16)

Nov 29th, 2024
24
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 3.43 KB | None | 0 0
  1. #include <iostream>
  2. #include <vector>
  3. #include <stack>
  4. #include <algorithm>
  5.  
  6. using namespace std;
  7.  
  8. class Graph {
  9. private:
  10.     int N;
  11.     int M;
  12.     vector<vector<int>> adj;
  13. public:
  14.     Graph(int n, int m) : N(n), M(m), adj(n + 1) {}
  15.     void addEdge(int u, int v) {
  16.         adj[u].push_back(v);
  17.     }
  18.     Graph getTranspose() const {
  19.         Graph transposed(N, M);
  20.         for (int u = 1; u <= N; ++u) {
  21.             for (int v : adj[u]) {
  22.                 transposed.addEdge(v, u);
  23.             }
  24.         }
  25.         return transposed;
  26.     }
  27.     int getN() const { return N; }
  28.     const vector<vector<int>>& getAdj() const { return adj; }
  29.     void dfs(int u, stack<int>& finishStack, vector<bool>& visited) const {
  30.         visited[u] = true;
  31.         for (int v : adj[u]) {
  32.             if (!visited[v]) {
  33.                 dfs(v, finishStack, visited);
  34.             }
  35.         }
  36.         finishStack.push(u);
  37.     }
  38. };
  39.  
  40. class StronglyConnectedComponents {
  41. private:
  42.     const Graph& graph;
  43.     Graph transposeGraph;
  44.     vector<int> component;
  45.     stack<int> finishStack;
  46.     int numberOfComponents;
  47. public:
  48.     StronglyConnectedComponents(const Graph& g)
  49.         : graph(g), transposeGraph(g.getTranspose()), component(g.getN() + 1, 0), numberOfComponents(0) {}
  50.     void findSCCs() {
  51.         // Первый DFS на исходном графике для заполнения конечного стека
  52.         vector<bool> visited(graph.getN() + 1, false);
  53.         for (int u = 1; u <= graph.getN(); ++u) {
  54.             if (!visited[u]) {
  55.                 graph.dfs(u, finishStack, visited);
  56.             }
  57.         }
  58.  
  59.         // Второй DFS на графике транспонирования в порядке завершения стека
  60.         vector<bool> visited2(transposeGraph.getN() + 1, false);
  61.         while (!finishStack.empty()) {
  62.             int u = finishStack.top();
  63.             finishStack.pop();
  64.             if (!visited2[u]) {
  65.                 numberOfComponents++;
  66.                 // Присваиваем номер компоненты с помощью итеративного DFS
  67.                 stack<int> dfsStack;
  68.                 dfsStack.push(u);
  69.                 visited2[u] = true;
  70.                 component[u] = numberOfComponents;
  71.                 while (!dfsStack.empty()) {
  72.                     int current = dfsStack.top();
  73.                     dfsStack.pop();
  74.                     for (int v : transposeGraph.getAdj()[current]) {
  75.                         if (!visited2[v]) {
  76.                             visited2[v] = true;
  77.                             component[v] = numberOfComponents;
  78.                             dfsStack.push(v);
  79.                         }
  80.                     }
  81.                 }
  82.             }
  83.         }
  84.     }
  85.     int getComponentCount() const {
  86.         return numberOfComponents;
  87.     }
  88.     vector<int> getComponents() const {
  89.         return component;
  90.     }
  91. };
  92.  
  93. int main() {
  94.     ios_base::sync_with_stdio(false);
  95.     cin.tie(NULL);
  96.  
  97.     int N, M;
  98.     cin >> N >> M;
  99.  
  100.     Graph graph(N, M);
  101.     for (int i = 0; i < M; ++i) {
  102.         int u, v;
  103.         cin >> u >> v;
  104.         graph.addEdge(u, v);
  105.     }
  106.  
  107.     StronglyConnectedComponents scc(graph);
  108.     scc.findSCCs();
  109.     vector<int> components = scc.getComponents();
  110.  
  111.     cout << scc.getComponentCount() << endl;
  112.     for (int u = 1; u <= N; ++u) {
  113.         cout << components[u] << " ";
  114.     }
  115.     cout << endl;
  116.  
  117.     return 0;
  118. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement