Cod sursa(job #661763)

Utilizator claudiumihailClaudiu Mihail claudiumihail Data 15 ianuarie 2012 08:27:22
Problema Componente tare conexe Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 1.89 kb
#include <fstream>
#include <iostream>
#include <vector>
#include <stack>
#include <bitset>

#define MAXN	100001

using namespace std;

typedef unsigned int uint32;
typedef vector<vector<int> > Graph;
typedef vector<vector<int> > Scc;

stack<uint32> stS;
stack<uint32> stP;
vector<int> vNodeCounters(MAXN, -1);
bitset<MAXN> isNodeAssigned;

uint32 uCounter;
uint32 numComp;

void CtcGabow(const Graph& graph, Scc& sccs, const uint32 node)
{
	vNodeCounters[node] = uCounter;
	uCounter++;
	
	stS.push(node);
	stP.push(node);
	
	for (uint32 i=0; i<graph[node].size(); ++i)
	{
		if (-1 == vNodeCounters[graph[node][i]])
		{
			CtcGabow(graph, sccs, graph[node][i]);
		}
		else
		{
			if (false == isNodeAssigned[graph[node][i]])
			{
				while (!stP.empty() && vNodeCounters[stP.top()] > vNodeCounters[graph[node][i]])
				{
					stP.pop();
				}
			}
		}
	}
	
	if (!stP.empty() && stP.top() == node)
	{
		while (!stS.empty() && stS.top() != node)
		{
			sccs[numComp].push_back(stS.top());
			isNodeAssigned[stS.top()] = true;
			stS.pop();
		}
		
		if (!stS.empty())
		{
			sccs[numComp].push_back(stS.top());
			isNodeAssigned[stS.top()] = true;
			stS.pop();
		}
		numComp++;

		stP.pop();
	}
}

int main()
{
	uint32 n, m;
	Graph graph;
	Scc sccs;
	fstream fin("ctc.in", fstream::in);
	fstream fout("ctc.out", fstream::out);
	
	fin >> n >> m;
	//cout << n << " " << m << endl;
	
	graph.resize(n);
	sccs.resize(n);
	
	for (uint32 i=0; i<m; ++i)
	{
		uint32 x, y;
		fin >> x >> y;
		
		graph[x-1].push_back(y-1);
	}
	
	for (uint32 i=0; i<n; ++i)
	{
		if (-1 == vNodeCounters[i])
		{
			CtcGabow(graph, sccs, i);
		}
	}
	
	fout << numComp << "\n";
	for (uint32 i=0; i<numComp; ++i)
	{
		for (uint32 j=0; j<sccs[i].size(); ++j)
		{
			fout << sccs[i][j]+1 << " ";
		}
		fout << "\n";
	}
	
	fin.close();
	fout.close();
	return 0;
}