Cod sursa(job #2793689)

Utilizator SebicaPGLSebastian Ionel SebicaPGL Data 3 noiembrie 2021 21:28:47
Problema Sortare topologica Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 5.45 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] = {0};
    int nodeDegree[200000] = {0};
    
// #pragma endregion

// #pragma region "secret" functions
    // void flushVisited(); // fills the visited array with zeroes 
// #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) {
    if(a != b) {
        adjacentList[a].push_back(b);
    }
}

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);  
            }
        }
    }

}


void Graph::topologicalSort() { // I m using the Kahn s algorithm.
    // create a queue 
    std::queue<int> nodeQueue;
    std::vector<int> result;

    // calculate the degree of every node
    for(int i = 0; i < numberOfElements; i++) {
        for(int j = 0; j < adjacentList[i].size(); j++) {
            nodeDegree[adjacentList[i][j]] += 1;
        }
    }

    // enqueue all the nodes with degree = 0;

    for(int i = 0; i < numberOfElements; i++) {
        if(nodeDegree[i] == 0) {
            nodeQueue.push(i);
        }
    }

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

        result.push_back(front);

        for(int i = 0; i < adjacentList[front].size(); i++) {
            int newNode = adjacentList[front][i];
            nodeDegree[newNode]--;

            if(nodeDegree[newNode] == 0) {
                nodeQueue.push(newNode);
            }
        }
    }

    for(int i : result) {
        fileOut << i + 1 << " ";
    }

}
// 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();
}