Cod sursa(job #2444512)

Utilizator alexoloieriAlexandru Oloieri alexoloieri Data 31 iulie 2019 17:27:59
Problema Componente tare conexe Scor 40
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 3.08 kb
#include <bits/stdc++.h>
using namespace std;

class sccKosarajuSharir
{
private:
#define SCC_KOSARAJU_CHECK_CREATED(ret) if (!created) return ret
#define uint unsigned int
#define pb push_back
    std::vector<uint> *graph, *transposedGraph;
    uint *postOrd, n, act;
    bool *nodeUsed;
    bool created;
    void firstDfs(uint x)
    {
        nodeUsed[x] = true;
        for (uint i=0; i<graph[x].size(); ++i)
        {
            if (nodeUsed[graph[x][i]]) continue;
            firstDfs(graph[x][i]);
        }
        postOrd[++act] = x;
    }
    void secondDfs(uint x, std::vector<uint> &cc)
    {
        cc.pb(x);
        nodeUsed[x] = false;
        for (uint i=0; i<transposedGraph[x].size(); ++i)
        {
            if (!nodeUsed[transposedGraph[x][i]]) continue;
            secondDfs(transposedGraph[x][i], cc);
        }
    }
public:
    sccKosarajuSharir():
        created(false), postOrd(nullptr), nodeUsed(nullptr), graph(nullptr), transposedGraph(nullptr) {}
    bool create(uint sz)
    {
        if (created) return false;
        graph = new std::vector<uint>[sz + 1];
        if (graph == nullptr) return false;
        transposedGraph = new std::vector<uint>[sz + 1];
        if (transposedGraph == nullptr)
        {
            delete[] graph;
            return false;
        }
        postOrd = new uint[sz + 1];
        if (postOrd == nullptr)
        {
            delete[] graph;
            delete[] transposedGraph;
            return false;
        }
        nodeUsed = new bool[sz + 1];
        if (nodeUsed == nullptr)
        {
            delete[] graph;
            delete[] transposedGraph;
            delete[] postOrd;
            return false;
        }
        n = sz + 1;
        for (uint i=0; i<n; ++i)
            nodeUsed[i] = 0;
        created = true;
        return true;
    }
    bool addEdge(uint x, uint y)
    {
        SCC_KOSARAJU_CHECK_CREATED(false);
        if (x >= n || y >=n) return false;
        graph[x].pb(y);
        transposedGraph[y].pb(x);
        return true;
    }
    bool computeSCC(std::vector<std::vector<uint>> &ans)
    {
        SCC_KOSARAJU_CHECK_CREATED(false);
        act = 0;
        for (uint i=1; i<n; ++i)
            if (!nodeUsed[i])
                firstDfs(i);
        for (uint i=act; i>0; --i)
            if (nodeUsed[postOrd[i]])
            {
                std::vector<uint> currCc;
                secondDfs(postOrd[i], currCc);
                ans.pb(currCc);
            }
        return true;
    }
};

int main()
{
    int n, m, x, y;
    freopen("ctc.in","r",stdin);
    freopen("ctc.out","w",stdout);
    scanf("%d %d",&n,&m);
    sccKosarajuSharir ks;
    ks.create(n);
    for (int i=1; i<=m; ++i)
    {
        scanf("%d %d",&x,&y);
        ks.addEdge(x,y);
    }
    vector<vector<unsigned int>> ans;
    ks.computeSCC(ans);
    printf("%u\n", ans.size());
    for (auto cc:ans)
    {
        printf("%u ", cc.size());
        for (auto x:cc)
            printf("%d ", x);
        printf("\n");
    }
    return 0;
}