Cod sursa(job #2795453)

Utilizator TonioAntonio Falcescu Tonio Data 6 noiembrie 2021 13:16:52
Problema Componente tare conexe Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 4.1 kb
#include <fstream>
#include <vector>
#include <queue>
#include <stack>
#include <iostream>

using namespace std;

const int noduriMAX = 100001;

class Graf
{
private:
	int nrNoduri;
	int nrMuchii;
	int plecareBFS;
	vector <vector<int>> adiacenta;
	void Tarjan(int nod, int nrPasi[], int minimPasi[],
		stack<int>* st, bool inSt[], vector<vector<int>>& afisare);
public:
	void GrafNeorientat(string fisier);
	void GrafOrientat(string fisier);
	void DFS(int start, bool vizitat[]);
	void NumaraCompCnx();
	void citireBFS();
	void BFS();
	void CTC();
};

void Graf::GrafNeorientat(string fisier)
{
	ifstream in(fisier);
	in >> nrNoduri >> nrMuchii;
	int start;
	int capat;
	adiacenta.resize(nrNoduri + 1);
	for (int i = 0; i < nrMuchii; ++i)
	{
		in >> start >> capat;
		adiacenta[start].push_back(capat);
		adiacenta[capat].push_back(start);
	}
	in.close();
}

void Graf::GrafOrientat(string fisier)
{
	ifstream in(fisier);
	in >> nrNoduri >> nrMuchii;
	int start;
	int capat;
	adiacenta.resize(nrNoduri + 1);
	for (int i = 0; i < nrMuchii; ++i)
	{
		in >> start >> capat;
		adiacenta[start].push_back(capat);
	}
	in.close();
}

void Graf::DFS(int start, bool vizitat[])
{
	vizitat[noduriMAX] = { false };
	vizitat[start] = true;
	for (int vecin : adiacenta[start])
	{
		if (!vizitat[vecin])
			DFS(vecin, vizitat);
	}
}

void Graf::NumaraCompCnx()
{
	ofstream out("dfs.out");
	int nrCompCnx = 0;
	bool vizitat[noduriMAX] = { false };
	for (int i = 1; i <= nrNoduri; ++i)
	{
		if (!vizitat[i])
		{
			DFS(i, vizitat);
			nrCompCnx++;
		}
	}
	out << nrCompCnx;
	out.close();
}

void Graf::citireBFS()
{
	ifstream in("bfs.in");
	in >> nrNoduri >> nrMuchii >> plecareBFS;
	int start;
	int capat;
	adiacenta.resize(nrNoduri + 1);
	for (int i = 0; i < nrMuchii; ++i)
	{
		in >> start >> capat;
		adiacenta[start].push_back(capat);
	}
	in.close();
}

void Graf::BFS()
{
	queue <int> coadaBFS;
	int distanta[noduriMAX] = { 0 };
	ofstream out("bfs.out");
	int copiePlecareBFS = plecareBFS;
	bool vizitat[noduriMAX] = { false };
	vizitat[copiePlecareBFS] = true;
	coadaBFS.push(copiePlecareBFS);
	while (!coadaBFS.empty())
	{
		copiePlecareBFS = coadaBFS.front();
		coadaBFS.pop();
		for (int vecin : adiacenta[copiePlecareBFS])
			if (!vizitat[vecin])
			{
				vizitat[vecin] = true;
				distanta[vecin] = distanta[copiePlecareBFS] + 1;
				coadaBFS.push(vecin);
			}		
	}
	for (int i = 1; i <= nrNoduri; ++i)
	{
		if (!vizitat[i])
			out << -1 << " ";
		else
			out << distanta[i] << " ";
	}
		
	out.close();
}

void Graf::Tarjan(int nod, int nrPasi[], int minimPasi[], stack<int>* st, bool inSt[], vector<vector<int>>& afisare)
{
	static int pas = 0;
	nrPasi[nod] = minimPasi[nod] = ++pas;
	st->push(nod);
	inSt[nod] = true;

	for (int vecin : adiacenta[nod])
	{
		if (nrPasi[vecin] == -1)
		{
			Tarjan(vecin, nrPasi, minimPasi, st, inSt, afisare);
			minimPasi[nod] = min(minimPasi[nod], minimPasi[vecin]);
		}
		else if (inSt[vecin] == true)
			minimPasi[nod] = min(minimPasi[nod], nrPasi[vecin]);
	}
	if (minimPasi[nod] == nrPasi[nod])
	{
		vector <int> auxAfisare;
		while (st->top() != nod)
		{
			auxAfisare.push_back(st->top()); //?
			inSt[st->top()] = false;
			st->pop();
		}
		auxAfisare.push_back(st->top());
		inSt[st->top()] = false;
		st->pop();
		afisare.push_back(auxAfisare);
	}
}

void Graf::CTC()
{
	int* nrPasi = new int[nrNoduri + 1];
	int* minimPasi = new int[nrNoduri + 1];
	bool* inSt = new bool[nrNoduri + 1];
	stack<int>* st = new stack<int>();
	vector < vector<int>> afisare;

	for (int i = 1; i <= nrNoduri; i++)
	{
		nrPasi[i] = -1;
		minimPasi[i] = -1;
		inSt[i] = false;
	}

	for (int i = 1; i <= nrNoduri; i++)
		if (nrPasi[i] == -1)
			Tarjan(i, nrPasi, minimPasi, st, inSt, afisare);

	ofstream out("ctc.out");
	out << afisare.size() << "\n";
	for (int i = 0; i < afisare.size(); ++i)
	{
		for (int j = 0; j < afisare[i].size(); ++j)
			out << afisare[i][j] << " ";
		out << "\n";
	}
	out.close();
}
int main()
{
	Graf g;
	g.GrafOrientat("ctc.in");
	g.CTC();
	return 0;
}