Cod sursa(job #944504)

Utilizator sorin2kSorin Nutu sorin2k Data 28 aprilie 2013 20:20:07
Problema Componente tare conexe Scor 60
Compilator cpp Status done
Runda Arhiva educationala Marime 2.64 kb
#include<fstream>
#include<iostream>
#include<cstring>
#include<vector>

using namespace std;

int *viz, *finish, timp, nrComp;
vector<int> *sol;
// Parcugerea in latimp, in care tinem cont si de vectorul finish.
// Pozitia i din finish retine nodul care termina pe pozitia i + 1. (Primul nod care termina va fi pe prima pozitie)
void DFS(vector<int> *adj, int start)
{
	int i;
	for(i = 0; i < (int)adj[start].size(); i++)
	{
		if(viz[adj[start][i]] == 0)
		{
			viz[adj[start][i]] = 1;
			DFS(adj, adj[start][i]);
		}
	}
	finish[timp++] = start; 
	// Ne formam un vector in care indicii sunt timpii de terminare a unui nod, iar valorile sunt chiar noduri care termina 
	// in acel timp. De exemplu, pe pozitia 0 va fi nodul care va 'termina' primul (adica nu pleaca muchii din el)
}

// Parcurgerea in latimp pentru graful transpus. Alta functie pentru a nu distruge vectorul finish
void DFST(vector<int> *adj, int start)
{
	int i;
	sol[nrComp].push_back(start + 1); // adaugam nodurile componentei curente in vectorul sol[nrComp]
	for(i = 0; i < (int)adj[start].size(); i++)
	{
		if(viz[adj[start][i]] == 0)
		{
			viz[adj[start][i]] = 1;
			DFST(adj, adj[start][i]);
		}
	}
}

// functia nu va fi apelata, vom retine graful transpus chiar de la citire!
vector<int> *transpose(vector<int> *adj, int n) 
{
	vector<int> *adjt = new vector<int>[n];
	int i, j;
	for(i = 0; i < n; i++)
	{
		for(j = 0; j < (int)adj[i].size(); j++)
		{
			adjt[adj[i][j]].push_back(i);
		}
	}
	return adjt;
}

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

	int n, m, u, v, i, j;
	vector<int> *adj, *adjt;
	fin >> n >> m;
	adj = new vector<int>[n];
	adjt = new vector<int>[n];
	sol = new vector<int>[n];
	for(i = 0; i < m; i++)
	{
		fin >> u >> v;
		u--;
		v--;
		adj[u].push_back(v);
		adjt[v].push_back(u);
	}
	viz = new int[n];
	finish = new int[n];
	memset(viz, 0, n * sizeof(int));
	timp = 0;
	// forul exterior parcurgerii grafului initial
	for(i = 0; i < n; i++)
	{
		if(viz[i] == 0)
		{
			viz[i] = 1;
			DFS(adj, i);
		}
	}
	memset(viz, 0, n * sizeof(int)); // resetam vectorul de vizite 
	// forum exterior parcurgerii grafului transpus
	// In ordinea inversa a timpilor calculati dupa DFS pe graful initial aplicam DFS pe graful transpus
	for(i = n - 1; i >= 0; i--)
	{
		if(viz[finish[i]] == 0)
		{
			viz[finish[i]] = 1;
			DFST(adjt, finish[i]);
			nrComp++; // calculam numarul componentelor
		}	
	}
	// Afisam solutia
	fout << nrComp << endl;
	for(i = 0; i < nrComp; i++)
	{
		for(j = 0; j < (int)sol[i].size(); j++)
			fout << sol[i][j] << " ";
		fout << endl;
	}
	return 0;
}