Cod sursa(job #2143417)

Utilizator stoianmihailStoian Mihail stoianmihail Data 25 februarie 2018 22:02:56
Problema Componente tare conexe Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 1.92 kb
#include <stdio.h>
#include <vector>
#include <assert.h>

using std::vector;

#define MAX_N 100000
#define MAX_M 200000

typedef struct {
  int v, next;
} list;

int N, M, numScc;
list l[MAX_M + 1];
int adj[MAX_N + 1];
int adjt[MAX_N + 1];
char seen[MAX_N + 1];
int scc[MAX_N + 1];
int ss, stack[MAX_N + 1];
vector <int> maintain[MAX_N + 1];

void addEdge(int u, int v, int pos) {
  l[pos].v = v;
  l[pos].next = adj[u];
  adj[u] = pos;
}

void dfs(int u) {
  int pos;
  seen[u] = 1;
  for (pos = adj[u]; pos; pos = l[pos].next) {
    if (!seen[l[pos].v]) {
      dfs(l[pos].v);
    }
  }
  stack[ss++] = u;
}

void topSort() {
  int u;
  for (u = 1; u <= N; u++) {
    if (!seen[u]) {
      dfs(u);
    }
  }
}

void reverse() {
  int u, pos, next;
  for (u = 1; u <= N; u++) {
    for (pos = adj[u]; pos; pos = next) {
      next = l[pos].next;
      l[pos].next = adjt[l[pos].v];
      adjt[l[pos].v] = pos;
      l[pos].v = u;
    }
  }
}

void dfst(int u) {
  int pos;
  scc[u] = numScc;
  for (pos = adjt[u]; pos; pos = l[pos].next) {
    if (!scc[l[pos].v]) {
      dfst(l[pos].v);
    }
  }
}

void kosaraju() {
  topSort();

  reverse();

  int i;
  for (i = N - 1; i >= 0; i--) {
    if (!scc[stack[i]]) {
      ++numScc;
      dfst(stack[i]);
    }
  }
}

int main(void) {
  FILE *f = fopen("ctc.in", "r");

  int i, u, v;
  fscanf(f, "%d %d", &N, &M);
  for (i = 1; i <= M; i++) {
    fscanf(f, "%d %d", &u, &v);
    addEdge(u, v, i);
  }
  fclose(f);

  kosaraju();

  for (u = 1; u <= N; u++) {
    maintain[scc[u]].push_back(u);
  }

  freopen("ctc.out", "w", stdout);
  fprintf(stdout, "%d\n", numScc);
  vector <int>::iterator it;
  for (i = 1; i <= numScc; i++) {
    for (it = maintain[i].begin(); it != maintain[i].end(); it++) {
      fprintf(stdout, "%d ", *it);
    }
    fprintf(stdout, "\n");
  }
  fclose(stdout);
  return 0;
}