Cod sursa(job #526261)

Utilizator ucc_5Usurelu Catalin ucc_5 Data 27 ianuarie 2011 21:18:43
Problema Componente tare conexe Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 1.66 kb
// idx[v]= numara nodurile in ordinea in care sunt descoperite
//owlink[v] = min { idx[u] | u este accesibil din v }. Prin urmare, v este radacina unei
//componente tare conexe daca si numai daca lowlink[v] = idx[v]

#include <fstream>
#include <stack>
#include <vector>
#define nmax  100002
using namespace std;

ifstream f("ctc.in");
ofstream g1("ctc.out");

int n,m,i,Index,idx[nmax],lowlink[nmax];
stack <int> s;
vector <int> g[nmax];
vector < vector <int> > ctc;
bool in_stack[nmax];

void citire ();
void afiseaza ();
void retine_ctc (int v);

void tarjan (int v)
{
  idx[v]=Index;
  lowlink[v]=Index;
  Index=Index+1;
  in_stack[v]=true;
  
  s.push(v);
  
  for (size_t i=0; i<g[v].size(); i++)
  {
    if (!idx[g[v][i]])
    {
      tarjan (g[v][i]);
      lowlink[v]=min(lowlink[v],lowlink[g[v][i]]);
    }
    else if (in_stack[g[v][i]])
      lowlink[v] = min(lowlink[v], idx[g[v][i]]);
  }
  if (lowlink[v] == idx[v])
    retine_ctc (v);
}

void ctc_tarjan ()
{
  Index=1;
  for (int i=1; i<=n; i++)
    if (!idx[i])
      tarjan (i);
}

int main ()
{
  citire ();
  ctc_tarjan ();
  afiseaza ();
  return 0;
}

void citire ()
{
  int x,y;
  f>>n>>m;
  for (int i=1; i<=m; i++)
  {
    f>>x>>y;
    g[x].push_back(y);
  }
  f.close ();
}

void retine_ctc (int v)
{
    int u;
    vector <int> componenta;
    do
    {
      u=s.top(); 
      componenta.push_back (u);
      in_stack[u]=false;
      s.pop ();
      
    }
    while (u!=v);
    ctc.push_back (componenta);
}

void afiseaza ()
{
    g1<<ctc.size ();
    for (size_t i=0; i<ctc.size (); i++)
    {
        g1<<'\n';
        for (int j=0; j<ctc[i].size (); j++)
            g1<<ctc[i][j]<<" ";
    }
    g1.close ();
}