Cod sursa(job #2793911)

Utilizator lolotbogdanLolot Stefan-Bogdan lolotbogdan Data 4 noiembrie 2021 09:24:34
Problema Componente tare conexe Scor 60
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 4.13 kb
#include <iostream>
#include <fstream>
#include <unordered_map>
#include <list>
#include <queue>
#include <stack>

using namespace std;

ifstream f("ctc.in");
ofstream o("ctc.out");

class Graf {
	int noduri, muchii;
	unordered_map<int, list<int>>vecini;
	unordered_map<int, bool> vizitat;
	stack<int>stiva_sortare_topologica;
	unordered_map<int, list<int>>vecini_transp;
	unordered_map<int, int>vizitat_transp;
	stack<int>timp_vizitare;
	unordered_map<int, list<int>>componente_tare_conexe;

public:
	Graf(int n, int m);
	int get_noduri();
	int get_muchii();
	int get_vizitat(int nod);
	void adauga_muchie_neorientat(int nod1, int nod2);
	void adauga_muchie_orientat(int nod1, int nod2);
	void sorteaza();
	void dfs(int nod);
	void componente_conexe();
	void bfs(int nod);
	void sortare_topologica();
	void tool_sortare_topologica(int nod);
	void dfs_graf_transpus(int nod, int rezultat);
	void tare_conexitate();
};

Graf::Graf(int n, int m)
{
	this->noduri = n;
	this->muchii = m;
	for (int i = 1; i <= n; i++)
		vizitat[i] = vizitat_transp[i] = 0;
}

int Graf::get_noduri()
{
	return this->noduri;
}

int Graf::get_muchii()
{
	return this->muchii;
}

int Graf::get_vizitat(int nod)
{
	return vizitat[nod];
}

void Graf::adauga_muchie_neorientat(int nod1, int nod2)
{
	vecini[nod1].push_back(nod2);
	vecini[nod2].push_back(nod1);
}

void Graf::adauga_muchie_orientat(int nod1, int nod2)
{
	vecini[nod1].push_back(nod2);
	vecini_transp[nod2].push_back(nod1);
}

void Graf::sorteaza()
{
	for (int i = 1; i <= noduri; i++)
		vecini[i].sort();
}

void Graf::dfs(int nod)
{
	//cout << nod << " ";
	vizitat[nod] = 1;

	for (auto i = vecini[nod].begin(); i != vecini[nod].end(); i++)
		if (vizitat[*i] != 1)
			dfs(*i);

	timp_vizitare.push(nod);
}

void Graf::dfs_graf_transpus(int nod, int rezultat)
{
	componente_tare_conexe[rezultat].push_back(nod);

	vizitat_transp[nod] = 1;

	for (auto i = vecini_transp[nod].begin(); i != vecini_transp[nod].end(); i++)
		if (vizitat_transp[*i] != 1)
			dfs_graf_transpus(*i, rezultat);
}

void Graf::componente_conexe()
{
	int sol = 0;
	sorteaza();

	for (int i = 1; i <= noduri; i++)
		if (vizitat[i] != 1)
		{
			sol += 1;
			dfs(i);
		}

	o << sol;
}

void Graf::tare_conexitate()
{
	int rezultat = 0;

	for (int i = 1; i <= noduri; i++)
		if (vizitat[i] != 1)
			dfs(i);

	while (timp_vizitare.size())
	{
		if (vizitat_transp[timp_vizitare.top()] != 1)
		{
			rezultat++;
			dfs_graf_transpus(timp_vizitare.top(), rezultat);
		}
		timp_vizitare.pop();
	}
	o << rezultat;
	
	for (int i = 1; i <= rezultat; i++)
	{
		o << "\n";
		componente_tare_conexe[i].sort();
		for (auto j = componente_tare_conexe[i].begin(); j != componente_tare_conexe[i].end(); j++)
			o << *j << " ";
	}
}

void Graf::bfs(int nod)
{
	int start = nod;
	queue<int>coada;
	vizitat[nod] = 1;
	coada.push(nod);
	unordered_map<int, int>distanta;

	for (int i = 1; i <= noduri; i++)
		distanta[i] = 0;

	while (coada.size())
	{
		nod = coada.front();
		//cout << nod << " ";
		coada.pop();
		for (auto i = vecini[nod].begin(); i != vecini[nod].end(); i++)
			if (!vizitat[*i])
			{
				vizitat[*i] = 1;
				coada.push(*i);
				distanta[*i] = distanta[nod] + 1;
			}
	}
	for (int i = 1; i <= noduri; i++)
		if (i != start && distanta[i] == 0)
			o << "-1" << " ";
		else
			o << distanta[i] << " ";
}

void Graf::tool_sortare_topologica(int nod)
{
	vizitat[nod] = 1;

	for (auto i = vecini[nod].begin(); i != vecini[nod].end(); i++)
		if (vizitat[*i] != 1)
			tool_sortare_topologica(*i);

	stiva_sortare_topologica.push(nod);
}

void Graf::sortare_topologica()
{
	for (int i = 1; i <= noduri; i++)
		if (vizitat[i] != 1)
			tool_sortare_topologica(i);

	while (stiva_sortare_topologica.size())
	{
		o << stiva_sortare_topologica.top() << " ";
		stiva_sortare_topologica.pop();
	}
}

int main()
{
	int N, M;

	f >> N >> M;

	Graf g(N, M);

	for (int i = 1; i <= M; i++)
	{
		int st, dr;
		f >> st >> dr;
		g.adauga_muchie_orientat(st, dr);
	}

	g.sorteaza();

	g.tare_conexitate();

	return 0;
}