void scc_dfs(const vector<vector<int> > &g, int u, bool addToStack = false) {
  for (int i = 0; i < (int)g[u].size(); ++i) {
    int v = g[u][i];
    if (scc[v] == inf) {
      scc[v] = scc[u];
      scc_dfs(g, v, addToStack);
    }
  }
  if (addToStack) S.push(u);
}
int kosaraju() {
  const int inf = int(1e9 + 7);
  int ans = 0;

  scc.assign(n, inf);
  for (int u = 0; u < n; ++u) {
    if (scc[u] != inf) continue;
    scc[u] = true;
    scc_dfs(g, u, true);
  }
  scc.assign(n, inf);
  while (!S.empty()) {
    int u = S.top();
    S.pop();
    if (scc[u] != inf) continue;
    scc[u] = ans++;
    scc_dfs(gt, u);
  }

  return ans;
}
Пример #3
0
pair<union_find, vi> scc(const vvi &adj) {
  int n = size(adj), u, v;
  order.clear();
  union_find uf(n); vi dag; vvi rev(n);
  rep(i,0,n) rep(j,0,size(adj[i])) rev[adj[i][j]].push_back(i);
  visited.resize(n);
  fill(visited.begin(), visited.end(), false);
  rep(i,0,n) if (!visited[i]) scc_dfs(rev, i);
  fill(visited.begin(), visited.end(), false);
  stack<int> S;
  for (int i = n-1; i >= 0; i--) {
    if (visited[order[i]]) continue;
    S.push(order[i]), dag.push_back(order[i]);
    while (!S.empty()) {
      visited[u = S.top()] = true, S.pop();
      uf.unite(u, order[i]);
      rep(j,0,size(adj[u]))
        if (!visited[v = adj[u][j]]) S.push(v); } }
  return pair<union_find, vi>(uf, dag); }
Пример #4
0
void scc_dfs(const vvi &adj, int u) {
  int v; visited[u] = true;
  rep(i,0,size(adj[u]))
    if (!visited[v = adj[u][i]]) scc_dfs(adj, v);
  order.push_back(u); }