Cod sursa(job #2200450)

Utilizator iuliaulialiaiaIulia Maria iuliaulialiaia Data 1 mai 2018 14:53:39
Problema Componente tare conexe Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 2.12 kb
#include <fstream>
#include <list>
#include <stack>

#define UNKNOWN -1

class Graph {
  int n;
  std::list<int> *adj;
  std::list<std::list<int>> scc;

  void SCCUtil(int v, int *ids, int *low_link, bool *stack_member, std::stack<int> &s) {
    static int id = 0;
    ids[v] = low_link[v] = id;
    id++;
    s.push(v);
    stack_member[v] = 1;

    for (auto neighbour = adj[v].begin(); neighbour != adj[v].end(); neighbour++) {
      if (ids[*neighbour] == UNKNOWN) {
        SCCUtil(*neighbour, ids, low_link, stack_member, s);
      }
      if (stack_member[*neighbour] == 1) {
        if (low_link[*neighbour] < low_link[v]) {
          low_link[v] = low_link[*neighbour];
        }
      }
    }
    if (low_link[v] == ids[v]) {
      std::list<int> aux;
      int u;
      do {
        u = s.top();
        s.pop();
        stack_member[u] = 0;
        aux.push_back(u);
      } while (u != v);
      scc.push_back(aux);
    }
  }

public:
  Graph(int n) {
    this->n = n;
    adj = new std::list<int>[n];
  }
  void addEdge(int u, int v) {
    adj[u].push_back(v);
  }
  std::list<std::list<int>> getSCC() {
    int *ids = new int[n];
    int *low_link = new int[n];
    bool *stack_member = new bool[n];
    std::stack<int> s;
    for (int i = 0; i < n; i++) {
      ids[i] = UNKNOWN;
      low_link[i] = UNKNOWN;
      stack_member[i] = 0;
    }
    for (int i = 0; i < n; i++) {
      if (ids[i] == UNKNOWN) {
        SCCUtil(i, ids, low_link, stack_member, s);
      }
    }
    delete[] stack_member;
    delete[] low_link;
    delete[] ids;
    return scc;
  }
  ~Graph() {
    delete[] adj;
  }
};

int main() {
  std::ifstream in;
  std::ofstream out;
  in.open("ctc.in");
  int n, m;
  int x, y;
  in >> n >> m;
  Graph g(n);
  for (int i = 0; i < m; i++) {
    in >> x >> y;
    x--;
    y--;
    g.addEdge(x, y);
  }
  in.close();
  std::list<std::list<int>> scc = g.getSCC();
  out.open("ctc.out");
  out << scc.size() << "\n";
  for (auto l = scc.begin(); l != scc.end(); l++) {
    std::list<int> ll = *l;
    for (auto i = ll.begin(); i != ll.end(); i++) {
      out << (*i + 1) << " ";
    }
    out << "\n";
  }
  out.close();

  return 0;
}