Pagini recente » Cod sursa (job #1518435) | Cod sursa (job #496846) | Cod sursa (job #569997) | Cod sursa (job #2510936) | Cod sursa (job #2930624)
#include <iostream>
#include <fstream>
#include <vector>
#include <stack>
using namespace std;
class Graph{
vector<vector<int>> adj; // lista de adiacenta
int V; // nr. de noduri
public:
Graph(int V=0);
Graph& operator=(const Graph& ob);
void resize(int S);
void addEdge(int v, int w);
void print() const;
friend ostream& operator<<(ostream& out, const Graph& ob);
void printSCC();
Graph getTranspose();
void firstDFS(int v, bool visited[], stack<int>& Stack);
void secondDFS(int v, bool visited[], vector<int>& SCC);
};
Graph::Graph(int V) {
this->V = V;
adj = vector<vector<int>>(V+1);
}
Graph& Graph::operator=(const Graph& ob){
if(this != &ob) {
this->V = ob.V;
this->adj = vector<vector<int>>(V+1);
int i = 0;
for (const auto &v: ob.adj) {
for (const auto &w: v)
this->addEdge(w, i);
i++;
}
}
return *this;
}
void Graph::resize(int S) {
adj = vector<vector<int>>(V+1);
}
void Graph::addEdge(int v, int w) {
adj[v].push_back(w);
}
void Graph::print() const {
int i = 0;
for (const auto &v: adj) {
cout << i << ": ";
for (const auto &w: v)
cout << w << " ";
cout << endl;
i++;
}
}
ostream& operator<<(ostream& out, const Graph& ob){
ob.print();
return out;
}
Graph Graph::getTranspose(){
Graph gT(V);
int i = 0;
for(const auto &v: adj) {
for (const auto &w: v)
gT.addEdge(i, w);
i++;
}
return gT;
}
void Graph::firstDFS(int v, bool visited[], stack<int>& Stack){
visited[v] = true;
for(const auto &w: adj[v]){
if(!visited[w])
firstDFS(w, visited, Stack);
}
Stack.push(v);
}
void Graph::secondDFS(int v, bool visited[], vector<int>& SCC){
SCC.push_back(v);
visited[v] = true;
for(const auto &w: adj[v])
if(!visited[w])
secondDFS(w, visited, SCC);
}
ofstream fout("ctc.out");
void Graph::printSCC() {
vector<vector<int>> allSCC;
stack<int> Stack;
bool *visited = new bool[V+1];
for(int i = 1; i <= V; i++)
visited[i] = false;
// Facem DFS pe g, iar in stiva vom avea nodurile in ordine inversa a momentului de finalizare
for(int i = 1; i <= V; i++)
if(!visited[i])
firstDFS(i, visited, Stack);
// Generam graful transpus al lui g
Graph gT;
gT = this->getTranspose();
for(int i = 1; i <= V; i++)
visited[i] = false;
// Facem DFS pe gT, iar nodul de start este primul element din stiva care nu a fost vizitat
while(!Stack.empty()){
int v = Stack.top();
Stack.pop();
if(!visited[v]) {
vector<int> SCC;
gT.secondDFS(v, visited, SCC);
allSCC.push_back(SCC);
}
}
fout << allSCC.size() << endl;
for(const auto &i: allSCC){
for(const auto &v: i)
fout << v << ' ';
fout << endl;
}
}
int main(){
ifstream fin("ctc.in");
int V, E;
// Citim graful g
fin >> V >> E;
Graph g(V);
for(int i = 0; i < E; i++) {
int v, w;
fin >> v >> w;
g.addEdge(v, w);
}
g.printSCC();
fout.close();
}