Pagini recente » Cod sursa (job #2718267) | Cod sursa (job #3153557) | Cod sursa (job #2741287) | Cod sursa (job #2493833) | Cod sursa (job #1748998)
#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;
}