Pagini recente » Cod sursa (job #2531860) | Cod sursa (job #678605) | Cod sursa (job #749915) | Cod sursa (job #230078) | Cod sursa (job #944502)
Cod sursa(job #944502)
#include<fstream>
#include<iostream>
#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]);
}
}
}
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];
sol = new vector<int>[n];
for(i = 0; i < m; i++)
{
fin >> u >> v;
u--;
v--;
adj[u].push_back(v);
}
viz = new int[n];
finish = new int[n];
for(i = 0; i < n; i++) // resetam vectorul de vizite
viz[i] = 0;
timp = 0;
// forul exterior parcurgerii grafului initial
for(i = 0; i < n; i++)
{
if(viz[i] == 0)
{
viz[i] = 1;
DFS(adj, i);
}
}
adjt = transpose(adj, n);
for(i = 0; i < n; i++) // resetam vectorul de vizite
viz[i] = 0;
// 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;
}