Pagini recente » Cod sursa (job #1397031) | Cod sursa (job #212845) | Cod sursa (job #2334088) | Cod sursa (job #311176) | Cod sursa (job #944508)
Cod sursa(job #944508)
#include<fstream>
#include<iostream>
#include<cstring>
#include<vector>
using namespace std;
int viz[100000], finish[100000], timp, nrComp;
vector<int> sol[100000], adj[100000], adjt[100000];
// 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(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[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(int start)
{
int i;
sol[nrComp].push_back(start + 1); // adaugam nodurile componentei curente in vectorul sol[nrComp]
for(i = 0; i < (int)adjt[start].size(); i++)
{
if(viz[adjt[start][i]] == 0)
{
viz[adjt[start][i]] = 1;
DFST(adjt[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;
fin >> n >> m;
for(i = 0; i < m; i++)
{
fin >> u >> v;
u--;
v--;
adj[u].push_back(v);
adjt[v].push_back(u);
}
// forul exterior parcurgerii grafului initial
for(i = 0; i < n; i++)
{
if(viz[i] == 0)
{
viz[i] = 1;
DFS(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(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;
}
fin.close();
fout.close();
return 0;
}