Cod sursa(job #1748998)

Utilizator lox010Andrei Ion lox010 Data 27 august 2016 17:29:27
Problema Componente tare conexe Scor 12
Compilator cpp Status done
Runda Arhiva educationala Marime 4.39 kb
#include <iostream>
#include <vector>
#include <map>
#include <stack>
#include <fstream>
#include <algorithm>

enum color { WHITE, GRAY, BLACK };

struct graph{

	unsigned int N; //number of vertices
	unsigned int M; //number of edges
	

	std::vector<std::pair<int, int> > edges;
	std::vector<std::pair<int, int> > edges_tr;
	std::vector<color> colors;
	std::vector<int> parents;
	std::vector<int> discover_time;
	std::vector<int> finishing_time;
};

std::stack<int> fin_time_stack;
std::map<int, std::vector<int> > SCC; //map of all the SCC

std::vector<int> adj_list(graph g, int vertex, bool is_transpose)
{
	std::vector<int> adjency_list;

	if (!is_transpose)
	{
		for (unsigned int i = 0; i < g.edges.size(); ++i)
		{
			if (g.edges[i].first == vertex)
				adjency_list.push_back(g.edges[i].second);
		}
	}
	else //if is transposed graph
	{
		for (unsigned int i = 0; i < g.edges_tr.size(); ++i)
		{
			if (g.edges_tr[i].first == vertex)
				adjency_list.push_back(g.edges_tr[i].second);
		}
	}
	return adjency_list;
}

graph dfs(graph g, bool is_transpose)
{
	std::stack<int> stack;

	int time = 0;

	for (unsigned int i = 0; i < g.N; ++i)
	{
		g.colors.push_back(WHITE);
		g.parents.push_back(0);
		g.discover_time.push_back(0);
		g.finishing_time.push_back(0);
	}
	for (unsigned int i = 0; i < g.N; ++i)
	{
		if (g.colors[i] == WHITE)
		{
			stack.push(i + 1);
			g.discover_time[i] = ++time;
			while (!stack.empty())
			{
				bool found_wite = false;
				int curr_vertex = stack.top();
				std::vector<int> adjency_list = adj_list(g, curr_vertex, is_transpose);
				
				for (unsigned int j = 0; j < adjency_list.size(); ++j)
				{
					if (g.colors[adjency_list[j] - 1] == WHITE) //if color of the neihbour node is WHITE
					{
						found_wite = true;
						g.colors[adjency_list[j] - 1] = GRAY;
						g.discover_time[adjency_list[j] - 1] = ++time;
						stack.push(adjency_list[j]);
						break;
					}
				}
				if (!found_wite)
				{
					//insert in stack by finishing times
					fin_time_stack.push(stack.top());

					g.finishing_time[stack.top() - 1] = ++time;
					g.colors[stack.top() - 1] = BLACK;					
					stack.pop();
				}
			}			
		}
	}
	return g;
}



//number of SCC
int nr_of_SCC = 0;

graph dfsT(graph g)
{
	int time = 0;
	std::stack<int> stack;

	for (unsigned int i = 0; i < g.N; ++i)
	{
		g.colors.push_back(WHITE);
		g.parents.push_back(0);
		g.discover_time.push_back(0);
		g.finishing_time.push_back(0);
	}
	while(!fin_time_stack.empty())
	{
		int i = fin_time_stack.top();
		fin_time_stack.pop();

		if (g.colors[i - 1] == WHITE)
		{
			nr_of_SCC++;
			std::vector<int> SCC_components;

			stack.push(i);
			g.discover_time[i - 1] = ++time;
			while (!stack.empty())
			{
				bool found_wite = false;
				int curr_vertex = stack.top();
				std::vector<int> adjency_list = adj_list(g, curr_vertex, true);

				//std::cout << curr_vertex << ' '; //pring vertices from the current SCC

				for (unsigned int j = 0; j < adjency_list.size(); ++j)
				{
					if (g.colors[adjency_list[j] - 1] == WHITE) //if color of the neihbour node is WHITE
					{
						found_wite = true;
						SCC_components.push_back(adjency_list[j]);
						g.colors[adjency_list[j] - 1] = GRAY;
						g.discover_time[adjency_list[j] - 1] = ++time;
						stack.push(adjency_list[j]);
						break;
					}
				}
				if (!found_wite)
				{
					g.finishing_time[stack.top() - 1] = ++time;
					g.colors[stack.top() - 1] = BLACK;
					stack.pop();
				}
			}
			SCC[nr_of_SCC - 1] = SCC_components;
		}
		
	}
	return g;
}

void kosaraju(graph g)
{
	graph dfs_g, dfs_tr_g;
	dfs_g = dfs(g, false);

	dfs_tr_g = dfsT(g);

}


int main()
{
	std::ifstream f_in;
	std::ofstream f_out;

	graph g;

	f_in.open("ctc.in");
	f_out.open("ctc.out");

	f_in >> g.N >> g.M;

	while (!f_in.eof())
	{
		int u = 0, v = 0;

		f_in >> u >> v;

		g.edges.push_back(std::make_pair(u, v));
		g.edges_tr.push_back(std::make_pair(v, u));
	}
	kosaraju(g);

	f_out << SCC.size() << std::endl;



	for (std::map<int, std::vector<int> >::iterator it = SCC.begin(); it != SCC.end(); ++it)
	{
		std::sort(it->second.begin(), it->second.end());
		for (unsigned int i = 0; i < it->second.size(); ++i)
		{
			f_out << it->second[i] << ' ';
		}
		f_out << std::endl;
	}

	f_in.close();
	f_out.close();

	return 0;
}