Cod sursa(job #3200243)

Utilizator cata00Catalin Francu cata00 Data 3 februarie 2024 21:49:52
Problema Componente tare conexe Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 1.96 kb
// Strongly connected components - Tarjan's algorithm.
#include <stdio.h>

const int MAX_NODES = 100'000;
const int MAX_EDGES = 200'000;
const int SEPARATOR = 0;

struct edge {
  int v, next;
};

struct node {
  int adj;
  int time_in;
  int low;
  bool on_stack;
};

node n[MAX_NODES + 1];
int st[MAX_NODES], ss;  // DFS stack
edge e[MAX_EDGES + 1];
int comp[2 * MAX_NODES], comp_ptr, num_comps;
int num_nodes, time;

void read_graph() {
  FILE* f = fopen("ctc.in", "r");
  int num_edges, u, v;
  fscanf(f, "%d %d", &num_nodes, &num_edges);
  for (int i = 1; i <= num_edges; i++) {
    fscanf(f, "%d %d", &u, &v);
    e[i] = { v, n[u].adj };
    n[u].adj = i;
  }
  fclose(f);
}

int min(int x, int y) {
  return (x < y) ? x : y;
}

void pop_scc(int last) {
  int v;
  do {
    v = st[--ss];
    n[v].on_stack = false;
    comp[comp_ptr++] = v;
  } while (v != last);
  comp[comp_ptr++] = SEPARATOR;
  num_comps++;
}

void dfs(int u) {
  n[u].time_in = n[u].low = ++time;
  n[u].on_stack = true;
  st[ss++] = u;

  for (int ptr = n[u].adj; ptr; ptr = e[ptr].next) {
    int v = e[ptr].v;
    if (!n[v].time_in) {
      // Traverse the white descendant and make a note of how high it can
      // climb.
      dfs(v);
      n[u].low = min(n[u].low, n[v].low);
    } else if (n[v].on_stack) {
      // We can climb to v's level.
      n[u].low = min(n[u].low, n[v].time_in);
    }
  }

  // If no vertex from u's subtree can climb higher than u, then the stack
  // from u to the top is a SCC.
  if (n[u].low == n[u].time_in) {
    pop_scc(u);
  }
}

void dfs_driver() {
  for (int u = 1; u <= num_nodes; u++) {
    if (!n[u].time_in) {
      dfs(u);
    }
  }
}

void write_components() {
  FILE* f = fopen("ctc.out", "w");
  fprintf(f, "%d\n", num_comps);
  for (int i = 0; i < comp_ptr; i++) {
    if (comp[i] == SEPARATOR) {
      fprintf(f, "\n");
    } else {
      fprintf(f, "%d ", comp[i]);
    }
  }
  fclose(f);
}

int main() {
  read_graph();
  dfs_driver();
  write_components();

  return 0;
}