Pagini recente » Cod sursa (job #598534) | Cod sursa (job #1822783) | Cod sursa (job #1227411) | Cod sursa (job #2821508) | Cod sursa (job #1755793)
#include <iostream>
#include <cstdio>
#include <vector>
#include <stack>
using namespace std;
class Graph {
public:
Graph(int num_nodes) : num_nodes_(num_nodes) {
edges_.resize(num_nodes_);
}
void AddEdge(int first_node, int second_node) {
edges_[first_node].push_back(second_node);
}
void Dfs(int node, vector<bool> &visited) {
visited[node] = true;
for (int i = 0; i < edges_[node].size(); ++i) {
int next_node = edges_[node][i];
if (!visited[next_node]) {
Dfs(next_node, visited);
}
}
node_ordering_.push(node);
}
void GetNodesInOrder() {
clog << "GetNodesInOrder()" << endl;
vector<bool> visited(num_nodes_, false);
for (int i = 0; i < num_nodes_; ++i) {
if (!visited[i]) {
Dfs(i, visited);
}
}
}
// Return the transposed graph
Graph *Transpose() {
clog << "Transpose()" << endl;
Graph *T = new Graph(num_nodes_);
for (int node = 0; node < num_nodes_; ++node) {
for (int next_node : edges_[node]) {
T->AddEdge(next_node, node);
}
}
return T;
}
int num_nodes() const {
return num_nodes_;
}
stack<int> node_ordering() {
return node_ordering_;
}
void reset_node_ordering() {
node_ordering_ = stack<int>();
}
private:
vector<vector<int>> edges_;
int num_nodes_;
stack<int> node_ordering_;
};
class CtcCounter {
public:
CtcCounter(Graph *G) : G_(G), counter_(0) {
clog << "CtcCounter()" << endl;
}
void Calculate(stack<int> node_ordering) {
clog << "CtcCounter.Calculate()" << endl;
vector<bool> visited(G_->num_nodes());
while (!node_ordering.empty()) {
int node = node_ordering.top();
node_ordering.pop();
if (!visited[node]) {
G_->Dfs(node, visited);
counter_++;
strong_components_.push_back(G_->node_ordering());
G_->reset_node_ordering();
}
}
}
void Output() {
printf("%d\n", counter_);
for (stack<int>& ctc : strong_components_) {
while (!ctc.empty()) {
printf("%d ", ctc.top() + 1);
ctc.pop();
}
printf("\n");
}
}
private:
Graph *G_;
int counter_;
vector<stack<int>> strong_components_;
};
int main() {
freopen("ctc.in","r",stdin);
freopen("ctc.out","w",stdout);
int num_nodes, num_edges;
scanf("%d %d", &num_nodes, &num_edges);
Graph *G = new Graph(num_nodes);
for (int i = 0; i < num_edges; ++i) {
int node, next_node;
scanf("%d %d", &node, &next_node);
G->AddEdge(node - 1, next_node - 1);
}
Graph *T = G->Transpose();
G->GetNodesInOrder();
stack<int> node_ordering = G->node_ordering();
CtcCounter *ctc_counter = new CtcCounter(T);
ctc_counter->Calculate(node_ordering);
ctc_counter->Output();
return 0;
}