Cod sursa(job #2788942)

Utilizator cristivasileVasile George-Cristian cristivasile Data 26 octombrie 2021 18:13:13
Problema Parcurgere DFS - componente conexe Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 4.48 kb
#include <fstream>
#include <algorithm>
#include <queue>
#include <iterator>
#include <vector>
#include <stack>

using namespace std;

ifstream f("dfs.in");
ofstream g("dfs.out");

constexpr int maxSize = 100001;

class Graph {

    vector<vector<int>> adjacencyLists;
    int nrNodes;
    bool isDirected;

public:
    Graph(int, bool);
    void initializeAdjacencyLists();

    void readEdges(int);
    void printDistancesToNode(int);
    void BFS(int, vector<int>&);
    int numberOfConnectedComponents();
    void DFS(int, vector<int>&);
};

Graph::Graph(int size = maxSize, bool isDirected = false) {
    nrNodes = size;
    this->isDirected = isDirected;
    initializeAdjacencyLists();
}


/// <summary>
/// initializes empty adjacency lists (vectors)
/// </summary>
void Graph::initializeAdjacencyLists() {
    for (int i = 0; i < nrNodes; i++) {
        vector<int> emptyAdjacencyVector;
        adjacencyLists.push_back(emptyAdjacencyVector);
    }
}

/// <summary>
/// reads a number of edges given as parameter
/// </summary>
void Graph::readEdges(int nrEdges) {
    int inNode, outNode;

    if (isDirected)
    {
        for (int i = 0; i < nrEdges; i++) {
            f >> outNode >> inNode;

            outNode--;
            inNode--;

            adjacencyLists[outNode].push_back(inNode);

        }
    }
    else
    {
        for (int i = 0; i < nrEdges; i++) {
            f >> outNode >> inNode;

            outNode--;
            inNode--;

            adjacencyLists[outNode].push_back(inNode);
            adjacencyLists[inNode].push_back(outNode);
        }
    }
}
/// <summary>
/// Prints the distance from a node given as parameter to all nodes in the graph, or -1 if they are inaccesible.
/// </summary>
/// <param name="startNode">the node for which distances are calculated</param>
void Graph::printDistancesToNode(int startNode) {

    vector<int> distancesArray(nrNodes, -1);
    distancesArray[startNode] = 0;          //distance from starting node to starting node is 0
    BFS(startNode, distancesArray);

    // iterate through distance vector and print
    for (int i = 0; i < nrNodes; i++)
        g << distancesArray[i] << " ";
}


/// <summary>
/// Does a breadth-first search and maps the distances to a vector<int> given as parameter.
/// </summary>
/// <param name="startNode"> starting node of search </param>
/// <param name="distances"> vector to map distances to </param>
void Graph::BFS(int startNode, vector<int>& distances) {
    int currentNode, currentDistance;
    queue<int> toVisit;
    toVisit.push(startNode);

    // while there still are accesible nodes that were not visited
    while (toVisit.empty() != true) {
        currentNode = toVisit.front();
        /// iterate through the current node's neighbors
        for (int neighboringNode : adjacencyLists[currentNode])
            if (distances[neighboringNode] == -1) {
                toVisit.push(neighboringNode);
                distances[neighboringNode] = distances[currentNode] + 1;
            }
        toVisit.pop();
    }
}


/// <summary>
/// computes number of connected components
/// </summary>
/// <returns></returns>
int Graph::numberOfConnectedComponents() {
    int nr = 0;
    vector<int> visited(nrNodes, 0);
    for (int i = 0; i < nrNodes; i++)
        if (visited[i] == 0) {
            nr++;
            DFS(i, visited);
        }
    return nr;
}

/// <summary>
/// Depth-first traversal that maps visited nodes in a vector of ints given as parameter.
/// </summary>
/// <param name="startNode">the start node of the traversal</param>
/// <param name="visited">visited nodes vector</param>
void Graph::DFS(int startNode, vector<int>& visited)
{
    int currentNode;
    stack<int> toVisit;

    toVisit.push(startNode);

    // while there still are accesible nodes that were not visited
    while (toVisit.empty() != true) {
        currentNode = toVisit.top();

        toVisit.pop();

        // if current node was not visited before
        if (visited[currentNode] == 0) {
            // iterate through the current node's neighbors
            for (auto node : adjacencyLists[currentNode])
                if (visited[node] == 0)
                    toVisit.push(node);

            visited[currentNode] = 1;
        }
    }
}

int n, m;
int main()
{
    f >> n >> m;
    Graph graf(n, false);
    graf.readEdges(m);
    g << graf.numberOfConnectedComponents();
}