Pagini recente » Cod sursa (job #3239764) | Cod sursa (job #1244463) | Cod sursa (job #1758175) | Cod sursa (job #3033326) | Cod sursa (job #1755787)
#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, stack<int> &nodes) {
// output nodes
nodes.push(node);
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, nodes);
}
}
}
stack<int> GetNodesInOrder() {
clog << "GetNodesInOrder()" << endl;
vector<bool> visited(num_nodes_, false);
stack<int> visited_nodes;
stack<int> node_ordering;
for (int i = 0; i < num_nodes_; ++i) {
if (!visited[i]) {
Dfs(i, visited, visited_nodes);
while (!visited_nodes.empty()) {
node_ordering.push(visited_nodes.top());
visited_nodes.pop();
}
}
}
return node_ordering;
}
// 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_;
}
private:
vector<vector<int>> edges_;
int num_nodes_;
};
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());
stack<int> visited_nodes;
while (!node_ordering.empty()) {
int node = node_ordering.top();
node_ordering.pop();
if (!visited[node]) {
G_->Dfs(node, visited, visited_nodes);
counter_++;
strong_components_.push_back(visited_nodes);
visited_nodes = stack<int>();
}
}
}
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();
stack<int> node_ordering = G->GetNodesInOrder();
CtcCounter *ctc_counter = new CtcCounter(T);
ctc_counter->Calculate(node_ordering);
ctc_counter->Output();
return 0;
}