Cod sursa(job #1430790)

Utilizator Arsenescu_Mihai_Catalin_322CAArsenescu Mihai Catalin Arsenescu_Mihai_Catalin_322CA Data 8 mai 2015 20:10:33
Problema Componente tare conexe Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 3.42 kb
#include <stack>
#include <iostream>
#include <vector>
#include <fstream>
#include <algorithm>
using namespace std;
typedef unsigned int uint;
class Node {
	int id;
	int discovery_time;
	int lowlink;
	
public:
	bool in_stack;
	Node(int id) : id(id) { reset(); }
	~Node() {}
	int get_id() { return id; }
	void set_time(int time) { discovery_time = time; }
	int get_time() { return discovery_time; }
	void set_lowlink(int x) { lowlink = x; }
	int get_lowlink() { return lowlink; }
	void reset() { discovery_time = UNSET; }
	bool visited() { return !(discovery_time == UNSET); }
	const static int UNSET = -1;
};
class Graph {
	vector<Node *> nodes;
	vector<vector<Node *> > edges;
	int time;
	stack<Node *> st;
	vector<vector<Node *> > solution;
	
public:
	Graph() {
		reset();
		fstream input("ctc.in", ios_base::in);
		int nodes_no, edges_no;
		input >> nodes_no >> edges_no;
		nodes = vector<Node *>(nodes_no + 1, NULL);
		edges = vector<vector<Node *> >(nodes_no + 1, vector<Node *>());
		for(int i = 1; i <= nodes_no; i++) {
			nodes.at(i) = new Node(i);
		}
		for(int i = 0; i < edges_no; i++) {
			int n1, n2;
			input >> n1 >> n2;
			edges[n1].push_back(nodes[n2]);
		}
		input.close();
	}
	~Graph() {
		for(uint i = 1; i < nodes.size(); i++) 
			delete nodes[i];
	}
	void reset() { 
		solution = vector<vector<Node *> >();
		st = stack<Node *>();
		time = 0;
		for(uint i = 1; i < nodes.size(); i++)
			nodes[i]->reset();
	}
	void print() {
		for(uint i = 1; i < edges.size(); i++) {
			cout << i << ": ";
			for(uint j = 0; j < edges[i].size(); j++)
				cout << edges[i][j]->get_id() << "--";
			cout << "\n";
		}
	}
	void ctc_tarjan() {
		reset();
		for(uint i = 1; i < nodes.size(); i++) {
			if(!nodes[i]->visited())
				tarjan(nodes[i]);
		}
		fstream output("ctc.out", ios_base::out);
		output << solution.size() << "\n";
		for(uint i = 0; i < solution.size(); i++) {
			for(uint j = 0; j < solution[i].size(); j++) 
				output << solution[i][j]->get_id() << " ";
			output << "\n";
		}
		output.close();
	}
	void tarjan(Node *node) {
		// cout << "Visiting node: " << node->get_id() << " at time: " << time << "\n";
		Node *neighbour;
		node->set_time(time);
		node->set_lowlink(time);
		time++;
		st.push(node);
		node->in_stack = true;
		for(uint i = 0; i < edges[node->get_id()].size(); i++) {
			neighbour = edges[node->get_id()][i];
			// cout << "-->Checking neighbour: " << neighbour->get_id() << " -->";
			if(!neighbour->visited()) {
				// cout << " visiting him \n";
				tarjan(neighbour);
				// cout << "[--] Came back to node: " << node->get_id() << " and neighbour: " 
				// << neighbour->get_id() << " lowlinks are: (" << node->get_lowlink()
				// << ", " << neighbour->get_lowlink() << ")\n";
				node->set_lowlink(min(node->get_lowlink(), neighbour->get_lowlink()));
			}
			else
				if(neighbour->in_stack) {
					// cout << " already visited with disc_time: " << neighbour->get_time();
					node->set_lowlink(min(node->get_lowlink(), neighbour->get_time()));
					// cout << " lowlink changed to: " << node->get_lowlink() << "\n";
				}
		}
		if(node->get_lowlink() == node->get_time()) {
			Node *n;
			vector<Node *> sol;
			do {
				n = st.top();
				st.pop();
				n->in_stack = false;
				sol.push_back(n);
			}
			while (node->get_id() != n->get_id());
			solution.push_back(sol);
		}
	}
	
};

int main() {
	Graph g;
	g.ctc_tarjan();
}