Cod sursa(job #1468853)

Utilizator tamionvTamio Vesa Nakajima tamionv Data 7 august 2015 06:03:36
Problema Componente tare conexe Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 2.1 kb
#include <vector>
#include <stack>
#include <fstream>
#include <iterator>
#include <algorithm>
using namespace std;

class recording_stack{
	vector<int> st;
	vector<int> num_aparitii;
	void clear(){
		while((!st.empty()) && num_aparitii[st.back()] == 0){
			st.pop_back(); } }
public:
	recording_stack(const int max_n): num_aparitii(max_n, 0){
		st.reserve(max_n); }
	void push(const int x){
		clear();
		st.push_back(x);
		++num_aparitii[x]; }
	void pop(){
		clear();
		--num_aparitii[st.back()];
		st.pop_back(); }
	int top(){
		clear();
		return st.back(); }
	bool empty(){
		clear();
		return st.empty(); }
	bool apare(const int x){
		return num_aparitii[x] > 0; }
	void scoate(const int x){
		num_aparitii[x] = 0; } };

void first_dfs(const vector<vector<int> >& graf, const int cur, vector<bool>& atins, recording_stack& st){
	for(const auto next : graf[cur]){
		if(!atins[next]){
			atins[next] = true;
			first_dfs(graf, next, atins, st); } }
	st.push(cur); }

void second_dfs(const vector<vector<int> >& graf, const int cur, vector<bool>& atins, vector<vector<int> >& componente){
	componente.back().push_back(cur);
	for(const auto next : graf[cur]){
		if(!atins[next]){
			atins[next] = true;
			second_dfs(graf, next, atins, componente); } } }

int main(){
	ifstream f("ctc.in");
	ofstream g("ctc.out");
	int n, m;
	f >> n >> m;
	vector<vector<int> > graf(n), graf_t(n);
	for(int i = 0, a, b; i < m; ++i){
		f >> a >> b;
		--a, --b;
		graf[a].push_back(b);
		graf_t[b].push_back(a); }
	recording_stack st(n);
	{
		vector<bool> atins(n, false);
		for(int i = 0; i < n; ++i){
			if(!atins[i]){
				atins[i] = true;
				first_dfs(graf, i, atins, st); } } }
	vector<vector<int> > componente;
	{
		vector<bool> atins(n, false);
		while(!st.empty()){
			componente.push_back(vector<int>());
			atins[st.top()] = true;
			second_dfs(graf_t, st.top(), atins, componente);
			st.pop();
			for(const auto x : componente.back()){
				st.scoate(x); } } }
	g << componente.size() << '\n';
	for(const auto& comp : componente){
		transform(begin(comp), end(comp), ostream_iterator<int>(g, " "), [](const int x){ return x+1; });
		g << '\n'; }
	return 0; }