Cod sursa(job #1442540)

Utilizator tweetyMarinescu Ion tweety Data 25 mai 2015 19:25:02
Problema Componente tare conexe Scor 0
Compilator cpp Status done
Runda Arhiva educationala Marime 2.88 kb
#include <fstream>
#include <iostream>
#include <vector>
#include <iterator>
#include <algorithm>
#include <stack>
#include <string.h>
using namespace std;

ifstream In("ctc.in");
ofstream Out("ctc.out");
vector<int>* Neighbours;
vector<vector<int> > Solution;
stack<int> Stack;
int* Indexes;
int* LowLinks;
bool* OnStack;
int NodesNo;
int EdgesNo;
int Index;

void alloc()
{
	Neighbours = new vector<int>[NodesNo];
	Indexes = new int[NodesNo];
	LowLinks = new int[NodesNo];
	OnStack = new bool[NodesNo];

	memset(Indexes, -1, sizeof(int) * NodesNo);
	memset(LowLinks, 0, sizeof(int)* NodesNo);
	memset(OnStack, 0, sizeof(bool)* NodesNo);
}

void dealloc()
{
	delete[] Neighbours;
	delete[] Indexes;
	delete[] LowLinks;
	delete[] OnStack;
}

void readData()
{
	In >> NodesNo >> EdgesNo;
	alloc();

	for (int i = 0, x, y; i != EdgesNo; ++i)
	{
		In >> x >> y;
		Neighbours[x - 1].push_back(y - 1);
	}

	In.close();
}

void printData()
{
	Out << Solution.size() << "\n";
	for (vector<vector<int> >::iterator it = Solution.begin(); it != Solution.end(); ++it)
	{
		vector<int> current = *it;
		for (vector<int>::iterator itr = current.begin(); itr != current.end(); ++itr)
			Out << *itr + 1 << " ";

		Out << "\n";
	}

	Out.close();
}

void setIndex(const int& node, const int& index)
{
	Indexes[node] = index;
}

void setLowLink(const int& node, const int& lowlink)
{
	LowLinks[node] = lowlink;
}

void setBoth(const int& node, const int& value)
{
	setIndex(node, value);
	setLowLink(node, value);
}

void addToStack(const int& node)
{
	Stack.push(node);
	OnStack[node] = true;
}

int removeFromStack()
{
	int node = Stack.top();
	Stack.pop();
	OnStack[node] = false;

	return node;
}

bool isIndexed(const int& node)
{
	return Indexes[node] != -1;
}

bool isOnStack(const int& node)
{
	return OnStack[node] == true;
}

int minimum(const int& val1, const int& val2)
{
	return val1 < val2 ? val1 : val2;
}

void makeSolution(const int& node)
{
	vector<int> solution;
	int fromStack = removeFromStack();
	solution.push_back(fromStack);

	while (fromStack != node)
	{
		fromStack = removeFromStack();
		solution.push_back(fromStack);
	}

	Solution.push_back(solution);
}

void Tarjan(const int& node)
{
	setBoth(node, Index++);
	addToStack(node);

	for (vector<int>::iterator it = Neighbours[node].begin(); it != Neighbours[node].end(); ++it)
		if (!isIndexed(*it))
		{
			Tarjan(*it);
			setLowLink(node, minimum(LowLinks[node], LowLinks[*it]));
		}
		else
			if (isOnStack(*it))
				setLowLink(node, minimum(LowLinks[node], LowLinks[*it]));

	if (Indexes[node] == LowLinks[node])
		makeSolution(node);
}

void solve()
{
	for (int i = 0; i != NodesNo; ++i)
		if (!isIndexed(i))
			Tarjan(i);
}

int main()
{
	readData();
	solve();
	printData();
	dealloc();

	system("pause");
	return 0;
}