Cod sursa(job #3252510)

Utilizator AdelaCorbeanuAdela Corbeanu AdelaCorbeanu Data 29 octombrie 2024 19:47:14
Problema Parcurgere DFS - componente conexe Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 4.36 kb
#include <bits/stdc++.h>

using namespace std;

enum GraphRepresentations {
    AdjacencyMatrix,
    AdjacencyList,
    EdgeList
};

struct GraphUtils {
protected:
    vector<int> color;
    vector<bool> visited;
    vector<int> discover_time;
    vector<int> finish_time;
    vector<int> level;
    vector<int> father;

    int current_color = 0;
    int current_time = 0;
};

class Graph : public GraphUtils {
private:
    // lista de adiacenta
    // neighbours[3] = {4, 5} are semnificatia ca vecinii lui 3 sunt 4 si 5
    vector<vector<int>> neighbours;

    // matrice de adiacenta
    // edge[3][5] = true are semnificatia ca exista muchie de la 3 la 5
    vector<vector<bool>> edge;

    // lista de muchii
    // edge_list[3] este a treia muchie din lista
    // edge_list[3].first este nodul de la care pleaca muchia 3
    // edge_list[3].second este nodul la care ajunge muchia 3
    vector<pair<int, int>> edge_list;

    size_t no_of_nodes;
    int no_of_edges;
    bool is_directed = false;

    void dfs_with_times(int start);
    void dfs_with_colors(int start);

public:
    void read_from_file(const string &file_name, GraphRepresentations representation, bool read_direction = false);
    void dfs_classic(int start, bool print = false);
    int get_connected_components_count();

    void read_from_stream(istream &fin, GraphRepresentations representation, bool read_direction = false);
};

void Graph::dfs_with_colors(int start) {
    color[start] = current_color;
    for (auto neighbour : neighbours[start]) {
        if (!color[neighbour]) {
            dfs_with_colors(neighbour);
        }
    }
}

int Graph::get_connected_components_count() {
    color.resize(no_of_nodes, 0);

    for (int node = 0; node < no_of_nodes; ++node) {
        if (!color[node]) {
            ++current_color;
            dfs_with_colors(node);
        }
    }

    return current_color;
}

void Graph::read_from_file(const string &file_name, GraphRepresentations representation, bool read_direction) {
    ifstream fin(file_name);
    read_from_stream(fin, representation, read_direction);
    fin.close();
}

void Graph::read_from_stream(istream &fin, GraphRepresentations representation, bool read_direction) {
    fin >> no_of_nodes >> no_of_edges;

    if (read_direction) {
        fin >> is_directed;
    }

    switch (representation) {
        case AdjacencyList:
            neighbours.resize(no_of_nodes);

            for (int edge_index = 0; edge_index < no_of_edges; ++edge_index) {
                int node1, node2;
                fin >> node1 >> node2;

                // Decomentati daca graful e indexat de la 1:
                --node1, --node2;

                neighbours[node1].push_back(node2);
                if (!is_directed) neighbours[node2].push_back(node1);
            }

            break;

        case AdjacencyMatrix:
            edge.resize(no_of_nodes, vector<bool>(no_of_nodes, false));

            for (int edge_index = 0; edge_index < no_of_edges; ++edge_index) {
                int node1, node2;
                fin >> node1 >> node2;

                // Decomentati daca graful e indexat de la 1:
                ///--node1, --node2;

                edge[node1][node2] = true;
                edge[node2][node1] = !is_directed || edge[node2][node1];
            }

            break;

        case EdgeList:
            edge_list.resize(no_of_edges);

            for (int edge_index = 0; edge_index < no_of_edges; ++edge_index) {
                int node1, node2;
                fin >> node1 >> node2;

                edge_list[edge_index] = {node1, node2};
            }

            break;
    }
}

void Graph::dfs_classic(int start, bool print) {
    visited[start] = true;
    if (print) cout << start << " ";

    for (auto neighbour : neighbours[start]) {
        if (!visited[neighbour]) {
            dfs_classic(neighbour, print);
        }
    }
}

void Graph::dfs_with_times(int start) {
    discover_time[start] = ++current_time;

    for (auto neighbour : neighbours[start]) {
        if (!discover_time[neighbour]) {
            father[neighbour] = start;
            level[neighbour] = level[start] + 1;

            dfs_with_times(neighbour);
        }
    }

    finish_time[start] = ++current_time;
}


int main()
{
    Graph graph_obj;
    graph_obj.read_from_file("dfs.in", AdjacencyList);

    ofstream fout("dfs.out");
    fout << graph_obj.get_connected_components_count();

    return 0;
}