Cod sursa(job #2342645)

Utilizator AndreiBadescuBadescu Andrei-Octavian AndreiBadescu Data 12 februarie 2019 23:34:27
Problema Componente tare conexe Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 2.05 kb
#include <fstream>
#include <vector>
#include <stack>

using namespace std;
typedef unsigned int uint;

ifstream fin("ctc.in");
ofstream fout("ctc.out");

class Graph
{
	uint V;
	vector<vector<uint>> adj;

	void SCC(const uint &node,
	         vector<uint> &lowlink,
	         vector<uint> &index,
	         vector<bool> &inStack,
	         stack <uint> &S,
	         vector<vector<uint>> &sol);
public:
	Graph(const uint V);
	void Add_edge(uint x, uint y);
	void Tarjan();
};

Graph::Graph(const uint V)
{
	this->V = V;
	adj.assign(V + 1, vector<uint>());
}

void Graph::Add_edge(uint x, uint y)
{
	adj[x].emplace_back(y);
}

void Graph::SCC(const uint &node,
                vector<uint> &lowlink,
                vector<uint> &index,
                vector<bool> &inStack,
                stack <uint> &S,
                vector<vector<uint>> &sol)
{
	static uint time;

	lowlink[node] = index[node] = ++time;
	S.push(node);
	inStack[node] = true;

	for (auto &i : adj[node])
	{
		if (!index[i])
		{
			SCC(i, lowlink, index, inStack, S, sol);
			lowlink[node] = min(lowlink[node], lowlink[i]);
		}
		else if (inStack[i])
		{
			lowlink[node] = min(lowlink[node], lowlink[i]);
		}
	}

	if (lowlink[node] == index[node])
	{
		sol.emplace_back(vector<uint>());

		while (S.top() != node)
		{
			sol.back().emplace_back(S.top());
			inStack[S.top()] = false;
			S.pop();
		}

		sol.back().emplace_back(S.top());
		inStack[S.top()] = false;
		S.pop();
	}
}

void Graph::Tarjan()
{
	vector<uint> lowlink(V + 1, 0), index(V + 1, 0);
	vector<vector<uint>> sol;
	vector<bool> inStack(V + 1, false);
	stack <uint> S;

	for (uint i = 1; i <= V; ++i)
	{
		if (!index[i])
			SCC(i, lowlink, index, inStack, S, sol);
	}

	fout << sol.size() << '\n';
	for (auto &i : sol)
	{
		for (auto &j : i)
		{
			fout << j << ' ';
		}
		fout << '\n';
	}
}

int main()
{
	uint n,m;
	fin >> n >> m;

	Graph G(n);

	for (uint x,y,i = 0; i < m; ++i)
	{
		fin >> x >> y;
		G.Add_edge(x,y);
	}

	G.Tarjan();
}