Cod sursa(job #1808139)

Utilizator rares00Foica Rares rares00 Data 17 noiembrie 2016 13:30:25
Problema Componente tare conexe Scor 0
Compilator cpp Status done
Runda Arhiva educationala Marime 2.45 kb
//graf orientat - afiseaza numarul si nodurile din componentele conexe (DFS, alocare dinamica)
#include <iostream>
#include <fstream>
using namespace std;
ifstream in("ctc.in");
ofstream out("ctc.out");

//structura listei de adiacenta
struct nod{
    //inf utila
    int vecin;
    //inf de leg
    struct nod *urm;
}*L[100005],*Lt[100005],*act;   //lista grafului normal, lista grafului transpus, actual
struct nod *CTC[100005];

int n,m,nrCTC;
bool viz[100005];
int stv[100005],vf;

void citire()
{
    int x,y;
    in>>n>>m;
    for(int i=1;i<=m;++i)
    {
        in>>x>>y;
        //adauga nod y la x in L
        act=new nod;
        act->vecin=y;
        act->urm=L[x];
        L[x]=act;
        //adauga x la y in Lt (graful transpus)
        act=new nod;
        act->vecin=x;
        act->urm=Lt[y];
        Lt[y]=act;
    }
}

void initViz()
{
    for(int i=1;i<=n;++i)
        viz[i]=0; //initializeaza vectorul viz
}

void dfs1(int nd)  //finishing times in D
{
    struct nod *actual;
    viz[nd]=1;
    //continua parcurgerea de la primul nod nevizitat
    actual=L[nd];
    while(actual!=NULL)
    {
        if(viz[actual->vecin]==0)
            dfs1(actual->vecin);
        actual=actual->urm;
    }
    stv[++vf]=nd;
}

void dfs2(int nd,int nr)    //SCC in Dt
{
    struct nod *p;
    viz[nd]=1; //marcheaza nodul ca vizitat
    //adauga nod la CTC corespunzatoare
    act=new nod;
    act->vecin=nd;
    act->urm=CTC[nr];
    CTC[nr]=act;
    //ia toti vecinii nodului
    p=Lt[nd];
    while(p!=NULL)
    {
        //apeleaza dfs pentru primul vecin nevizitat
        if(viz[p->vecin]==0)
            dfs2(p->vecin,nr);
        p=p->urm;
    }
}

int main()
{
    citire();

    //parcurge in adancime graful si retine nodurile (in stiva)
    //in ordinea completarii lor
    initViz();
    dfs1(1);

    //parcurge in adancime graful transpus in ordine inversa a completarii nodurilor
    //si afiseaza componentele tare conexe formate
    initViz();
    while(vf)
    {
        if(viz[stv[vf]]==1)
            --vf;
        else
            ++nrCTC, dfs2(stv[vf],nrCTC);
    }

    //afiseaza numarul si nodurile din componentele tare conexe
    out<<nrCTC<<"\n";
    for(int i=1;i<=nrCTC;++i)
    {
        act=CTC[i];
        while(act!=NULL)
        {
            out<<act->vecin<<" ";
            act=act->urm;
        }
        out<<"\n";
    }

    return 0;
}