Cod sursa(job #2792992)

Utilizator SebicaPGLSebastian Ionel SebicaPGL Data 2 noiembrie 2021 17:24:30
Problema Sortare topologica Scor 0
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 5.17 kb
#include <vector>
#include <stack>
#include <iostream>
#include <cstring>
#include <utility>
#include <fstream>
#include <queue>

std::ifstream fileOpen("sortaret.in");
std::ofstream fileOut("sortaret.out");

// I will modify the dfs for the topologicalSort

class Graph
{
  
// #pragma region declarations
    int numberOfElements;
    std::vector<int> adjacentList[100000];
    int visitedNodes[100000];
    int nodeDegree[100000] = {0};
    
// #pragma endregion

// #pragma region "secret" functions
    void flushVisited();
    void recursionForSort(int node, std::stack<int>& storeStack);
// #pragma endregion

public:

// #pragma region constructors
    Graph(int numberOfElements);
// #pragma endregion

// #pragma region functions
    void addEdge(int a, int b);
    void printGraph();
    void dfsRec(int node);
    void dfsIter(int node);
    void bfs(int node);
    void topologicalSort();
    void increaseDegree(int node);
// #pragma endregion

};

// #pragma region functions related to the class

void Graph::increaseDegree(int node) {
    nodeDegree[node] += 1;
}

void Graph::addEdge(int a, int b) {

    adjacentList[a].push_back(b);
    adjacentList[b].push_back(a);
}

void Graph::printGraph() {

    for(int node = 1; node <= numberOfElements; node++) {
        std::cout << "Nodul " << node << " are lista:";
        for(auto x : adjacentList[node]) {
            std::cout << "->" << x;
        }
        std::cout << "\n";
    }
}

void Graph::dfsRec(int node) {

    // Rec for recursive method
    if(visitedNodes[node] == 1){
        return;
    }
    visitedNodes[node] = 1;
    std::cout << node << " ";
    for(int adjacentNode : adjacentList[node]) {
        dfsRec(adjacentNode);
    }
}

void Graph::dfsIter(int node) {

    std::stack<int> nodeStack;
    // 1. push the node
    nodeStack.push(node);
    visitedNodes[node] = 1;
    // std::cout << node << " ";

    // 2. Iterate through the adjacentList 
    while(!nodeStack.empty()){
        // verify the top and then pop it.
        int top = nodeStack.top();
        if(visitedNodes[top] == 0) {
            // std::cout << top << " ";
            visitedNodes[top] = 1;
        }
        nodeStack.pop();

        for(int theOtherNodes : adjacentList[top]) {
            if(visitedNodes[theOtherNodes] == 0) {
                nodeStack.push(theOtherNodes);  
            }
        }
    }

}

// sa ma pis pe geeksforgeeks 

void Graph::recursionForSort(int node, std::stack<int>& storeStack) {

    // this is just the recursive dfs but you push the current node onto the stack

    visitedNodes[node] = 1;

    for(int adjacentNode : adjacentList[node]) {
        if(visitedNodes[adjacentNode] == 0) {
            recursionForSort(adjacentNode, storeStack);
        }
    }

    storeStack.push(node);
}

// void Graph::topologicalSort() {

//     std::stack<int> printStack;

//     for(int i = 0; i < numberOfElements; i++) {
//         if(visitedNodes[i] == 0) {
//             recursionForSort(i, printStack);
//         }
//     }

//     while(printStack.empty() == 0) {
//         fileOut << printStack.top() + 1 << " ";
//         printStack.pop();
//     }

// }

void Graph :: topologicalSort() {
    std::vector<int> sorted;
    sorted.reserve(100000);

    for(int i = 0; i < numberOfElements; i++) {
        // checking the nodeDegree array;
        if(nodeDegree[i] == 0) {
            sorted.push_back(i);
        }
    }

    for(int i = 0; i < numberOfElements; i++) {
        for(int adjacentNode : adjacentList[i]) {
            nodeDegree[adjacentNode] --;

            if(nodeDegree[adjacentNode] == 0) {
                sorted.push_back(adjacentNode);
            }
        }
    }

    for(int sortedNode : sorted) {
        fileOut << sortedNode + 1 << " ";
    }
}

void Graph::bfs(int node) {

    int distance[100000] = {0};

    std::queue<int> nodeQueue;
    visitedNodes[node] = 1;
    nodeQueue.push(node);

    while(!nodeQueue.empty()) {
        int front = nodeQueue.front();
        nodeQueue.pop();

        for(auto theOtherNodes : adjacentList[front]) {
            if(visitedNodes[theOtherNodes] == 0) {
                visitedNodes[theOtherNodes] = 1;
                nodeQueue.push(theOtherNodes);
                distance[theOtherNodes] = distance[front] + 1;
            }
        }
    }
    for(int i = 0; i < numberOfElements; i++) {
        if(visitedNodes[i] != 0) {
            fileOut << distance[i] << " ";
        }
        else {
            fileOut << -1 << " ";
        }
    }
}

void Graph::flushVisited() {
    std::memset(visitedNodes, 0, 100000);
}

Graph::Graph(int numberOfElements) : numberOfElements(numberOfElements) {
    flushVisited();
    
}
// #pragma endregion

int main()
{
    int nodes, edges;

    fileOpen >> nodes >> edges;

    Graph *biConexGraph = new Graph(nodes);

    int x, y;

    while(fileOpen >> x >> y) {
        biConexGraph->addEdge(x - 1, y - 1);
        biConexGraph->increaseDegree(x - 1);
        biConexGraph->increaseDegree(y - 1);
    }

    biConexGraph->topologicalSort();
}