Cod sursa(job #1480523)

Utilizator stoianmihailStoian Mihail stoianmihail Data 2 septembrie 2015 18:23:42
Problema Componente tare conexe Scor 100
Compilator c Status done
Runda Arhiva educationala Marime 2.83 kb
#include <stdio.h>
#include <stdlib.h>

#define Smerenie 200001
#define Nadejde 100001

typedef struct {
  int v, next;
} list;

int N, M;
int adj[Nadejde];                 // capetele listelor de adiacenta in G.
list l[Smerenie];                 // lista arcelor alocata static.
int adjt[Nadejde];                // capetele listelor de adiacenta in Gt.int numScc, scc[Nadejde];    // scc[u] este scc-ul din care face parte "u".
char seen[Nadejde];               // seen[u] este 1 doar daca nodul "u" a fost vizitat in dfs().
int numScc, scc[Nadejde];         // scc[u] este componenta tare conexa din care face parte "u".
int numSeen, order[Nadejde];      // sortarea topologica a grafului.
int freq[Nadejde], *com[Nadejde]; // nodurile Scc-urilor.

/** Adauga-l pe "v" la lista de adiacenta a lui "u" in "graph". **/
void addEdge(int *graph, int u, int v, int pos) {
  l[pos].v = v;
  l[pos].next = graph[u];
  graph[u] = pos;
}

/** Transpune graful. **/
void transpose() {
  int u, pos, next;
  for (u = 1; u <= N; u++) {
    for (pos = adj[u]; pos; pos = next) {
      next = l[pos].next;
      addEdge(adjt, l[pos].v, u, pos);
    }
  }
}

/** Exploreaza recursiv nodul "u" in G. **/
void dfs(int u) {
  int pos;
  if (!seen[u]) {
    seen[u] = 1;
    for (pos = adj[u]; pos; pos = l[pos].next) {
      dfs(l[pos].v);
    }
    order[++numSeen] = u;
  }
}

/** Sortarea topologica a grafului. **/
void topSort() {
  int u;
  for (u = 1; u <= N; u++) {
    dfs(u);
  }
}

/** Parcurge recursiv nodul "u" in Gt. **/
void dfst(int u) {
  int pos;
  if (!scc[u]) {
    freq[numScc]++;
    scc[u] = numScc;
    for (pos = adjt[u]; pos; pos = l[pos].next) {
      dfst(l[pos].v);
    }
  }
}

/** Algoritmul lui Kosaraju. **/
void kosaraju() {
  int i;
  topSort();
  transpose();
  for (i = N; i > 0; i--) {
    if (!scc[order[i]]) {
      numScc++;
      dfst(order[i]);
    }
  }
}

/** Aloca dinamic un vector de marime "size" pentru componenta "u". **/
void alloc(int u, int *size) {
  com[u] = (int*)calloc(*size, sizeof(int));
  (*size) = 0;
}

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

  /* Citeste graful. */
  fscanf(f, "%d %d", &N, &M);
  for (i = 1; i <= M; i++) {
    fscanf(f, "%d %d", &u, &v);
    addEdge(adj, u, v, i);
  }
  fclose(f);

  f = fopen("ctc.out", "w");

  /* Determina componentele tari conexe. */
  kosaraju();

  /* Construieste scc-urile . */
  for (i = 1; i <= numScc; i++) {
    alloc(i, &freq[i]);
  }
  for (u = 1; u <= N; u++) {
    com[scc[u]][freq[scc[u]]++] = u;
  }
  fprintf(f, "%d\n", numScc);
  for (u = 1; u <= numScc; u++) {
    for (i = 0; i < freq[u]; i++) {
      fprintf(f, "%d ", com[u][i]);
    }
    fputc('\n', f);
  }
  fclose(f);

  /// Multumim Doamne!
  puts("Doamne ajuta!");
  return 0;
}