Cod sursa(job #2671962)

Utilizator killerdonuttudor nicolae killerdonut Data 12 noiembrie 2020 21:28:26
Problema Componente tare conexe Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 2.09 kb
#include <iostream>
#include <fstream>
#include <stack>
#include <vector>
#include <algorithm>

using namespace std;

#define node graphVertexes[nodeIndex]
#define neighbor graphVertexes[neighborIndex]

const int N_MAX = 1e5 + 1;

struct TarjanVertex{
    int index, tarjanIndex = -1, lowlink;
    bool onStack = false;
};

vector <int> graph[N_MAX];
stack <int> stk;
vector <TarjanVertex> graphVertexes;
vector <vector <int>> solutions;

int nextAvailableIndex = 1;

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

void Tarjan(int nodeIndex)
{
    node.tarjanIndex = nextAvailableIndex;
    node.lowlink = nextAvailableIndex;
    nextAvailableIndex++;
    stk.push(nodeIndex);
    node.onStack = true;

    for(auto neighborIndex: graph[node.index])
    {
        if(neighbor.tarjanIndex == -1)
        {
            Tarjan(neighbor.index);
            node.lowlink = min(neighbor.lowlink, node.lowlink);
        }
        else if (neighbor.onStack == true)
        {
            node.lowlink = min(neighbor.tarjanIndex, node.lowlink);
        }        
    }

    if(node.tarjanIndex == node.lowlink)
    {
        vector <int> sol;
        int neighborIndex;
        do
        {
            neighborIndex = stk.top();
            sol.push_back(neighborIndex);
            stk.pop();
            neighbor.onStack = false;
        } while (neighborIndex != nodeIndex);  

        solutions.push_back(sol);      
    }
}

int main()
{
    int n, m;

    fin >> n >> m;

    graphVertexes.resize(n + 1);
    for(int i = 1; i <= n; i++)
    {
        graphVertexes[i].index = i;
    }

    for(int i = 0, st, dr; i < m; i++)
    {
        fin >> st >> dr;
        graph[st].push_back(dr);
    }

    for(int i = 1; i <= n; i++)
    {
        if(graphVertexes[i].tarjanIndex != -1)
            continue;

        Tarjan(i);
    }


    fout << solutions.size() << '\n';

    for(auto sol: solutions)
    {
        for(auto val: sol)
        {
            fout << val << ' ';
        }

        fout << '\n';
    }

    return 0;
}