Pagini recente » Cod sursa (job #1947794) | summer1 | Cod sursa (job #698490) | Cod sursa (job #2646371) | Cod sursa (job #2788942)
#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();
}