Cod sursa(job #2817600)

Utilizator RoberttoPopescu Paullo Robertto Karloss Robertto Data 13 decembrie 2021 21:47:07
Problema Componente tare conexe Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 3.6 kb
#include    <fstream>
#include    <iostream>
#include    <vector>
#include    <stack>

using namespace std;

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

struct muchie {
    int destinatie, cost, capacitate;

    muchie(int destinatie, int cost, int capacitate) : destinatie(destinatie), cost(cost), capacitate(capacitate) {}
};

class Graf {
private:
    int nrNoduri, nrMuchii;
    bool eOrientat, arePonderi, areCapacitati;
    vector<vector<muchie>> listaDeAdiacenta;
public:
    Graf(int nrNoduri, int nrMuchii, bool eOrientat, bool arePonderi, bool areCapacitati);

    void citire();

    void componenteTareConexe();

private:
    void DFSsortareTopologica(int nodPlecare, stack<int> &stiva, vector<int> &vizitat);

    void DFSgrafTranspus(int nodPlecare, vector<vector<int>> &componente, int &nr, vector<int> &vizitat,
                         vector<vector<muchie>> &listaDeAdiacentaTranspusa);
};

void Graf::DFSsortareTopologica(int nodPlecare, stack<int> &stiva, vector<int> &vizitat) {
    vizitat[nodPlecare] = 1;
    for (auto &i: listaDeAdiacenta[nodPlecare])
        if (!vizitat[i.destinatie])
            DFSsortareTopologica(i.destinatie, stiva, vizitat);
    stiva.push(nodPlecare);
}

void Graf::DFSgrafTranspus(int nodPlecare, vector<vector<int>> &componente, int &nr, vector<int> &vizitat,
                           vector<vector<muchie>> &listaDeAdiacentaTranspusa) {
    vizitat[nodPlecare] = 2;
    componente[nr].push_back(nodPlecare);
    for (auto &i: listaDeAdiacentaTranspusa[nodPlecare])
        if (vizitat[i.destinatie] == 1)
            DFSgrafTranspus(i.destinatie, componente, nr, vizitat, listaDeAdiacentaTranspusa);
}

void Graf::componenteTareConexe() {
    vector<vector<muchie>> listaDeAdiacentaTranspusa(nrNoduri + 1, vector<muchie>());
    for (int i = 1; i <= nrNoduri; i++)
        for (auto &j: listaDeAdiacenta[i])
            listaDeAdiacentaTranspusa[j.destinatie].push_back(muchie(i, j.cost, j.capacitate));

    vector<int> vizitat(nrNoduri + 1, 0);
    vector<vector<int>> componente(nrNoduri + 1, vector<int>());
    stack<int> stiva;
    for (int i = 1; i <= nrNoduri; i++)
        if (!vizitat[i])
            DFSsortareTopologica(i, stiva, vizitat);

    int nr = 0;
    while (!stiva.empty()) {
        int nodCurent = stiva.top();
        if (vizitat[nodCurent] == 1) {
            nr++;
            DFSgrafTranspus(nodCurent, componente, nr, vizitat, listaDeAdiacentaTranspusa);
        }
        stiva.pop();
    }
    fout << nr << "\n";
    for (int i = 1; i <= nr; i++) {
        for (auto &j: componente[i])
            fout << j << " ";
        fout << "\n";
    }
}

int main() {
    int nrNoduri, nrMuchii;
    fin >> nrNoduri >> nrMuchii;
    Graf g1(nrNoduri, nrMuchii, true, false, false);
    g1.citire();
    g1.componenteTareConexe();

    return 0;
}

void Graf::citire() {
    int sursa, destinatie, cost, capacitate;
    for (int i = 1; i <= nrMuchii; i++) {
        fin >> sursa >> destinatie;
        if (arePonderi)
            fin >> cost;
        else
            cost = 0;
        if (areCapacitati)
            fin >> capacitate;
        else
            capacitate = 0;
        listaDeAdiacenta[sursa].push_back(muchie(destinatie, cost, capacitate));
        if (!eOrientat)
            listaDeAdiacenta[destinatie].push_back(muchie(sursa, cost, capacitate));
    }
}

Graf::Graf(int nrNoduri, int nrMuchii, bool eOrientat, bool arePonderi, bool areCapacitati) {
    this->nrNoduri = nrNoduri;
    this->nrMuchii = nrMuchii;
    this->eOrientat = eOrientat;
    this->arePonderi = arePonderi;
    this->areCapacitati = areCapacitati;
    listaDeAdiacenta.resize(nrNoduri + 1, vector<muchie>());
}