Cod sursa(job #3238505)

Utilizator Traian_7109Traian Mihai Danciu Traian_7109 Data 25 iulie 2024 23:07:15
Problema Componente tare conexe Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 1.63 kb
#include <stdio.h>
#include <vector>

#define MAXN 100000

static inline int min(int a, int b) {
  return a < b ? a : b;
}

std::vector<int> nodes[MAXN], g[MAXN];

struct Tarjan {
  int idx[MAXN], lowlink[MAXN], ptr, instack[MAXN], stiva[MAXN], sp,
                                          comp[MAXN], ncomp;
  
  void dfs(int nod) {
    int i, aux;
    
    lowlink[nod] = idx[nod] = ++ptr;
    instack[nod] = 1;
    stiva[sp++] = nod;
    
    for(i = 0; i < (int)g[nod].size(); i++) {
      if(idx[g[nod][i]] == 0) {
        dfs(g[nod][i]);
        lowlink[nod] = min(lowlink[nod], lowlink[g[nod][i]]);
      } else if(instack[g[nod][i]]) {
        lowlink[nod] = min(lowlink[nod], lowlink[g[nod][i]]);
      }
    }
    
    if(idx[nod] == lowlink[nod]) {
      do {
        aux = stiva[--sp];
        instack[aux] = 0;
        comp[aux] = ncomp;
      } while(aux != nod);
      ncomp++;
    }
  }
  
  int solve(int n) {
    int i;
    
    for(i = 0; i < n; i++) {
      idx[i] = instack[i] = 0;
    }
    ptr = sp = ncomp = 0;
    for(i = 0; i < n; i++) {
      if(idx[i] == 0) {
        dfs(i);
      }
    }
    return ncomp;
  }
} ctc;

int main() {
  int n, m, i, u, v, j;
  
  #ifndef LOCAL
    freopen("ctc.in", "r", stdin);
    freopen("ctc.out", "w", stdout);
  #endif
  
  scanf("%d%d", &n, &m);
  for(i = 0; i < m; i++) {
    scanf("%d%d", &u, &v);
    g[--u].push_back(--v);
  }
  
  printf("%d\n", ctc.solve(n));
  for(i = 0; i < n; i++) {
    nodes[ctc.comp[i]].push_back(i);
  }
  for(i = 0; i < ctc.ncomp; i++) {
    for(j = 0; j < (int)nodes[i].size(); j++) {
      printf("%d ", nodes[i][j] + 1);
    }
    fputc('\n', stdout);
  }
  
  return 0;
}