Cod sursa(job #2824114)

Utilizator MaxamPJORares Daniel MaxamPJO Data 30 decembrie 2021 23:56:26
Problema Componente tare conexe Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 3.6 kb
#include <iostream>
#include <fstream>
#include <limits>
//"ctc.in"
std::ifstream fin("ctc.in");
std::ofstream fout("ctc.out");

struct node {
    int key;
    node* next;
};

enum COLOR {
    WHITE, GRAY, BLACK
};

bool dfs(node** g, int n, int nod, COLOR* vizitat, int* sortT, int& indexT) {
    vizitat[nod] = GRAY;
    
    node* p = g[nod];
    bool EsortT = true;
    while (p) {
        if (vizitat[p->key]) {
            if(vizitat[p->key]==GRAY) EsortT = false;
        }
        else
        {
           
            EsortT = dfs(g, n, p->key, vizitat, sortT, indexT) && EsortT;
            
        }
        p = p->next;
    }
    vizitat[nod] = BLACK;
    indexT--;
    sortT[indexT] = nod;
    
    return EsortT;
}
void strongconnect(node** g, int n, int nod, int &index, node* scc, node*& stack, int* ids, int* lowlink, bool* onStack) {
    ids[nod] = index;
    lowlink[nod] = index;
    index++;
    node* p = new node;
    p->key = nod;
    p->next = stack;
    stack = p;
    onStack[nod] = true;
    
    p = g[nod];
    while (p) {
        if (ids[p->key] == -1) {
            strongconnect(g, n, p->key, index, scc, stack, ids, lowlink, onStack);
            lowlink[nod] = std::min(lowlink[nod], lowlink[p->key]);
        }
        else {
            if (onStack[p->key]) {
                lowlink[nod] = std::min(lowlink[nod], ids[p->key]);
            }
        }
        p = p->next;
    }
    
    if (ids[nod] == lowlink[nod]) {
        int prev=0;
        int adj;
        bool first = true;
        scc[0].key++;
        do {
            p = stack;
            stack = stack->next;
            adj = p->key;
            delete(p);
            onStack[adj] = false;
            scc[adj].key = 0;            
            scc[adj].next = scc + prev;
            prev = adj;
        } while (adj != nod);
        scc[nod].key = 1;
    }
}
node* tarjan_scc(node** g, int n) {
    int index=0;
    node* scc = new node[n+1];
    scc[0].key = 0;
    node* stack = NULL;
    int* ids = new int[n + 1];
    int* lowlink = new int[n + 1];
    bool* onStack = new bool[n + 1];
    for (int i = 0; i <= n; i++) {
        ids[i] = -1;
        lowlink[i] = std::numeric_limits<int>::max();;
        onStack[i] = false;
    }
    for (int i = 1; i <= n; i++) {
        if (ids[i] == -1) {
            strongconnect(g, n, i, index, scc, stack, ids, lowlink, onStack);
        }
    }
    return scc;
}
int main()
{
    int n, m;
 
    fin >> n >> m;
    node** g = new node * [n + 1];

    for (int i = 1; i <= n; i++) {
        g[i] = NULL;
    }
    int u, v;
    for (int i = 0; i < m; i++) {
        fin >> u >> v;
        node* p = new node;
        p->next = g[u];
        p->key = v;
        g[u] = p;
    }
    /*for (int i = 1; i <= n; i++) {
        node* p = g[i];
        std::cout << i << ": ";
        while (p) {
            std::cout << p->key << " ";
            p = p->next;
        }
        putchar('\n');
    }*/
    node* scc = tarjan_scc(g, n);
    fout << scc[0].key<<"\n";
    for (int i = 1; i <= n; i++) {
        if (scc[i].key == 1) {
            node* p = scc[i].next;
            scc[i].key = -1;
            fout << i << " ";
            while (p != scc) {
                p->key = -1;
                fout << p-scc << " ";
                p = p->next;
            }
            fout << "\n";
        }

        /*for (int j = 1; j <= n; j++) {
            if (scc[j].key == i) {
                fout << j << " ";
            }
        }*/
    }
    fin.close();
    fout.close();
}