Pagini recente » Cod sursa (job #2822722) | Cod sursa (job #2075709) | Cod sursa (job #1571165) | Cod sursa (job #701446) | Cod sursa (job #3252510)
#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;
}