Cod sursa(job #3355799)

Utilizator ridicheTudor Diaconu ridiche Data 26 mai 2026 10:58:39
Problema Componente tare conexe Scor 30
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 3.4 kb
// why do i keep trying to do oop although i know it makes me 10x slower and the code at the end is even worse......
#include <fstream>
#include <vector>
#include <algorithm>

#warning In this world, its either mukbang or be mukbanged

using namespace std;

ifstream cin("ctc.in");
ofstream cout("ctc.out");

struct CondensedGraphNode {
    vector<int> nodes;
    vector<CondensedGraphNode*> nxt;
};

int curExitTime = 0; vector<bool> vis;
void dfs(vector<vector<int>>& originalNxt, int node, vector<int>& storeExitTimeHere)
{
    curExitTime++;
    if (vis[node])
        return;
    vis[node] = true;
    for (auto nn : originalNxt[node])
    {
        dfs(originalNxt, nn, storeExitTimeHere);
    }
    storeExitTimeHere[node] = curExitTime;
}

vector<int> exitTime;

bool cmp(int a, int b) {
    return exitTime[a] > exitTime[b];
}

void dfs2(vector<vector<int>> nxt, int pos, vector<CondensedGraphNode*>& whereIs, CondensedGraphNode* addr)
{
    if (whereIs[pos] != nullptr)
        return;
    whereIs[pos] = addr;
    addr->nodes.push_back(pos);
    for (auto it:nxt[pos])
    {
        dfs2(nxt, it, whereIs, addr);
    }
}

vector<CondensedGraphNode*> korasaju(vector<vector<int>> originalNxt) {
    // make prv
    vector<vector<int>> originalPrv;
    for (unsigned i = 0; i < originalNxt.size(); i++)
        originalPrv.push_back({});
    for (unsigned i = 0; i < originalNxt.size(); i++)
    {
        for (auto j : originalNxt[i])
        {
            originalPrv[j].push_back(i);
        }
    }

    // get exit time
    exitTime.resize(originalNxt.size());
    curExitTime = 0;
    vis.clear();
    vis.resize(originalNxt.size());
    for (unsigned i = 0; i < originalNxt.size(); i++)
    {
        if (!vis[i])
            dfs(originalNxt, i, exitTime);
    }

    // sort by it
    vector<int> ordering;
    for (unsigned i = 0; i < originalNxt.size(); i++)
        ordering.push_back(i);
    sort(ordering.begin(), ordering.end(), cmp);

    fill(vis.begin(), vis.end(), false);
    vector<CondensedGraphNode*> ret;
    vector<CondensedGraphNode*> whereIs(originalNxt.size());
    for (auto pos : ordering)
    {
        if (whereIs[pos] == nullptr)
        {
            ret.push_back(new CondensedGraphNode());
            dfs2(originalPrv, pos, whereIs, ret.back());
        }
    }

    for (unsigned curNode = 0; curNode < originalNxt.size(); curNode++)
    {
        for (auto otherNode : originalNxt[curNode])
        {
            if (whereIs[curNode] != whereIs[otherNode])
                whereIs[curNode]->nxt.push_back(whereIs[otherNode]);
        }
    }
    return ret;
}

int n, m;
vector<vector<int>> nxt;

int main()
{
    cin >> n >> m;
    nxt.resize(n);
    for (int i = 0; i < m; i++)
    {
        int u, v;
        cin >> u >> v;
        u--; v--;
        nxt[u].push_back(v);
    }
    vector<CondensedGraphNode*> condensed = korasaju(nxt);
    /* Debug
    for (int i = 0; i < condensed.size(); i++) {
        printf("%i:\n   init: ", i);
        for (auto it:condensed[i]->nodes)
            printf("%i ", it);
        printf("\n   nxt size %i\n", condensed[i]->nxt.size());
    }
    // */
    cout << condensed.size() << "\n";
    for (auto it:condensed)
    {
        for (auto it2:it->nodes)
        {
            cout << it2+1 << " ";
        }
        cout << "\n";
    }
    return 0;
}