Cod sursa(job #2929084)

Utilizator EduardSanduSandu Eduard Alexandru EduardSandu Data 24 octombrie 2022 16:20:34
Problema Componente tare conexe Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 2.16 kb
/// 4. https://infoarena.ro/problema/ctc

/// Solutia prezenta este bazata pe algoritmul lui Kosaraju, care are rolul de a gasi 
/// componentele tare conexe bazandu-ne pe graful transpus al grafului in cauza. Astfel, adaugam pe 
/// stiva la o prima parcurgere a grafului initial toate nodurile in ordinea accesarii lor,
/// iar apoi, in functie de cine a fost vizitat primul, mai parcurgem odata in adancime graful transpus, iar fiecare dfs
/// pe care il facem pe acel graf va reprezenta o componenta tare conexa. In principiu, daca facem
/// abstractie de notiunea de "orientat", algoritmul lui kosaraju imi verifica daca un ciclu se regaseste si in 
/// graful transpus, lucru ce garanteaza conditia de drum de la nodul x la nodul y, dar si vice-versa.

/// Complexitatea este O(n+m), avand 2 dfs uri 

#include <bits/stdc++.h>
using namespace std;

ifstream fin("ctc.in");
ofstream fout("ctc.out");

int n,m,nr;
vector<vector<int>> v, vt, sol;
vector<int> vis;
vector<int> order;

void dfs(int nod)
{
    vis[nod] = 1;
    for(int i=0; i<v[nod].size(); i++)
    {
        if(!vis[v[nod][i]])
            dfs(v[nod][i]);
    }
    order.push_back(nod); /// adaugam in stiva fiecare nod
}

void dfst(int nod)
{
    vis[nod] = 1;
    sol[nr].push_back(nod);
    for(int i=0; i<vt[nod].size(); i++)
    {
        if(!vis[vt[nod][i]])
            dfst(vt[nod][i]);
    }
}

int main()
{
    int a, b;
    fin>>n>>m;
    v.resize(n+1);
    vt.resize(n+1);
    for(int i=1; i<=m; i++)
    {
        fin>>a>>b;
        v[a].push_back(b);
        vt[b].push_back(a);
    }
    vis.resize(n+1, 0);
    /// dfs pe graful initial

    for(int i=1; i<=n; i++)
    {
        if(!vis[i])
            dfs(i);
    }

    fill(vis.begin(), vis.end(), 0);
    reverse(order.begin(), order.end());
    for(int i=0; i<order.size(); i++)
    {
        if(!vis[order[i]])
        {
            sol.push_back({});
            dfst(order[i]);
            nr++;
        }
    }
    fout<<nr<<'\n';
    for(int i=0; i<nr; i++)
    {
        for(int j=0;j<sol[i].size();j++)
            fout<<sol[i][j]<<' ';
        fout<<'\n';
    }
    return 0;
}