Cod sursa(job #1755793)

Utilizator Luncasu_VictorVictor Luncasu Luncasu_Victor Data 11 septembrie 2016 01:40:42
Problema Componente tare conexe Scor 60
Compilator cpp Status done
Runda Arhiva educationala Marime 2.54 kb
#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;
}