Cod sursa(job #3272110)

Utilizator AndreeaHzmAndreea Huzum AndreeaHzm Data 28 ianuarie 2025 14:10:12
Problema Sortare topologica Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 2.69 kb
#include <fstream>
#include <vector>
#include <stack>

#define maxi 100001

using namespace std;

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

class Graf {
    int nrNoduri, nrMuchii; // Numarul de noduri si muchii din graf
    int x, y;               // Nodurile care definesc o muchie (x -> y)
    int vizitat[maxi] = {0}; // Vector pentru a marca nodurile vizitate
    vector<int> *adiacenta; // Lista de adiacenta pentru graful orientat

public:
    Graf();
    ~Graf();

    void citireSortareTopologica(); // Citirea grafului orientat
    void DFS2(int nodPlecare, stack<int> &stiva); // Parcurgere DFS pentru sortare topologica
    void sortareTopologica(); // Sortarea topologica a grafului
};

Graf::Graf() {
    nrNoduri = nrMuchii = x = y = 0;
    adiacenta = new vector<int>[maxi]; // Alocare memorie pentru lista de adiacenta
}

Graf::~Graf() {
    delete[] adiacenta; // Eliberare memorie pentru lista de adiacenta
}

// Functie pentru citirea grafului orientat
void Graf::citireSortareTopologica() {
    fin >> nrNoduri >> nrMuchii; // Citim numarul de noduri si muchii
    for (int i = 1; i <= nrMuchii; i++) {
        fin >> x >> y;               // Citim fiecare muchie (x -> y)
        adiacenta[x].push_back(y);   // Adaugam nodul y ca vecin al nodului x
    }
}

// Functie recursiva pentru parcurgerea in adancime (DFS)
void Graf::DFS2(int nodPlecare, stack<int> &stiva) {
    vizitat[nodPlecare] = 1; // Marcarea nodului curent ca vizitat
    for (auto i: adiacenta[nodPlecare]) { // Parcurgem toti vecinii nodului curent
        if (!vizitat[i]) { // Daca vecinul nu a fost vizitat
            DFS2(i, stiva); // Apel recursiv pentru vecinul respectiv
        }
    }
    stiva.push(nodPlecare); // Adaugam nodul in stiva dupa ce am terminat parcurgerea vecinilor
}

// Functie pentru sortarea topologica a grafului
void Graf::sortareTopologica() {
    stack<int> stiva; // Stiva in care vom stoca nodurile in ordinea sortarii topologice

    // Pornim DFS pentru fiecare nod care nu a fost vizitat
    for (int i = 1; i <= nrNoduri; ++i) {
        if (!vizitat[i]) {
            DFS2(i, stiva);
        }
    }

    // Afisam nodurile in ordinea din stiva (sortare topologica)
    while (!stiva.empty()) {
        fout << stiva.top() << " "; // Nodurile sunt extrase in ordinea corecta
        stiva.pop();
    }
}

int main() {
    Graf g1; // Cream un obiect al clasei Graf
    g1.citireSortareTopologica(); // Citim graful din fisier
    g1.sortareTopologica(); // Realizam sortarea topologica si afisam rezultatul

    fin.close(); // Inchidem fisierul de intrare
    fout.close(); // Inchidem fisierul de iesire

    return 0;
}