Cod sursa(job #2662026)

Utilizator retrogradLucian Bicsi retrograd Data 23 octombrie 2020 12:07:26
Problema Componente tare conexe Scor 60
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 1.57 kb
#include <bits/stdc++.h>

using namespace std;
using ull = unsigned long long;

vector<vector<ull>> adj, jda;
vector<ull> vis;
vector<int> stk, comp;

void AddEdge(int a, int b) {
  adj[a][b / 64] |= (1ULL << (b % 64));
  jda[b][a / 64] |= (1ULL << (a % 64));
}

int Pop(vector<ull>& a, vector<ull>& b) {
  for (int i = 0; i < (int)a.size(); ++i) {
    ull msk = (a[i] & (~b[i]));
    if (msk) 
      return __builtin_ctzll(msk) + i * 64;
  }
  return -1;
}

template<int Phase>
void DFS(int node) {
  vis[node / 64] |= (1LL << (node % 64));
  while (true) {
    int vec = Pop((Phase == 0 ? adj : jda)[node], vis);
    if (vec == -1) break;
    DFS<Phase>(vec);
  }
  (Phase == 0 ? stk : comp).push_back(node);
}

void Solve(ostream& cout) {
  int n = adj.size();
  
  vis.assign(n / 64 + 1, 0);
  for (int node = 0; node < n; ++node) {
    if (!(vis[node / 64] & (1ULL << (node % 64))))
      DFS<0>(node);
  }
  
  fill(vis.begin(), vis.end(), 0); 
  vector<int> ccs_end;
  for (int i = n - 1; i >= 0; --i) {
    int node = stk[i];
    if (!(vis[node / 64] & (1ULL << (node % 64)))) {
      DFS<1>(node);
      ccs_end.push_back(comp.size());
    }
  }

  cout << ccs_end.size() << '\n';
  int b = 0;
  for (auto e : ccs_end) {
    for (int i = b; i < e; ++i)
      cout << comp[i] + 1 << " ";
    cout << '\n';
    b = e;
  }
}

int main() {
  ifstream cin("ctc.in");
  ofstream cout("ctc.out");
  int n, m; cin >> n >> m;
  adj.assign(n, vector<ull>(n / 64 + 1, 0));
  jda = adj;
  for (int i = 0; i < m; ++i) {
    int a, b; cin >> a >> b; --a; --b;
    AddEdge(a, b);
  }
  Solve(cout);
  return 0;
}