Pagini recente » Cod sursa (job #283789) | Cod sursa (job #841196) | Cod sursa (job #3207956) | Cod sursa (job #2598085) | Cod sursa (job #2487831)
//Cerchez 3 - tare-conexitate + pdf graf_definitii
//Desc unui graf orientat in componente tare-conexe
//Complexitatea alg este:
// cu liste de adiacenta - O(n+m)
// cu matricea de adiacenta - probabil O(n^2)
//--> reprezentare prin lista de adiacenta - dinamic
/*
1. Parcurg graful in adancime si numerotez vf grafului in postordine - in ordinea crescatoare a timpilor de finish
- varful x este numerotat dupa ce toti succesorii sai au fost numerotati
2. Se determina graful transpus AT ( il initializez inca de la citire)
3. Se parcurge graful TRANSPUS in adancime, considerand vf in ordinea inversa a vizitarii lor in parcurgerea DFS a grafului initial
- in ordinea din vectorul postordine
4. Fiecare subgraf obtinut in parcurgerea DFS a grafului transpus reprezinta componenta tare-conexa a grafului initial
*/
#include <iostream>
#include <vector>
#include <fstream>
#define NMax 100005
using namespace std;
//vector comp conexe
vector<vector<int>> vecConnex;
int n, nr, nrc;
int *A[NMax], *AT[NMax];
int postordine[NMax], viz[NMax];
void citire();
void afisare(int);
void DFS(int);
void DFST(int);
int* myRealloc(int*, int);
int main()
{
citire();
//parcurgem graful DFS, determinand ordinea varfurilor
for (int i = 1; i <= n; i++)
if (!viz[i]) DFS(i);
//parcurgem DFS graful transpus, prelucrand varfurile in postordine
for (int i = n; i > 0; i--)
if (viz[postordine[i]])
//componenta tare-conexa din care face parte varful curent nu a fost determinata
{
//cout << "Componenta tare-conexa " << ++nrc << ": ";
++nrc;
vecConnex.push_back(vector<int>());
DFST(postordine[i]);
}
afisare(nrc);
return 0;
}
//init listele de adiacenta - A si AT(graful transpus)
void citire()
{
fstream fin("ctc.in");
int x, y, m;
fin >> n >> m;
//aloc memorie pentru fiecare varf
for (int i = 1; i <= n; i++)
{
A[i] = new int[1];
A[i][0] = 0;
AT[i] = new int[1];
AT[i][0] = 0;
}
for (int i = 0; i < m; i++)
{
fin >> x >> y;
//initializez lista de adiacenta
A[x][0]++;
A[x] = myRealloc(A[x], A[x][0] + 1);
A[x][A[x][0]] = y;
//iinitializez list de adiacenta a grafului TRANSPUS AT
AT[y][0]++;
AT[y] = myRealloc(AT[y], AT[y][0] + 1);
AT[y][AT[y][0]] = x;
}
fin.close();
}
//parcurgerea in adancime si numerotarea vf in ordinea crescatoare a timpilor de finish
void DFS(int x)
{
viz[x] = 1;
for (int i = 1; i <= A[x][0]; i++)
if (!viz[A[x][i]])
DFS(A[x][i]);
postordine[++nr] = x;
}
//parcurgerea grafului TRANSPUS in adancime (DFST) considerand vf in ordinea inversa a viz lor in parcurgerea DFS
//(parcurgerea in ordinea din vectorul postordine)
void DFST(int x)
{
viz[x] = 0;
vecConnex.back().push_back(x);
//cout << x << ' ';
for (int i = 1; i <= AT[x][0]; i++)
if (viz[AT[x][i]])
DFST(AT[x][i]);
}
int* myRealloc(int A[], int newSize)
{
int* tmp = new int[newSize];
while (--newSize >= 0)
{
tmp[newSize] = A[newSize];
}
delete[] A;
A = tmp;
return A;
}
void afisare(int)
{
ofstream fout("ctc.out");
fout << nrc<<endl;
for (std::vector<vector<int>>::iterator it = vecConnex.begin(); it != vecConnex.end(); ++it)
{
for (std::vector<int>::iterator it2 = it->begin(); it2 != it->end(); ++it2)
fout << *it2<<' ';
fout << endl;
}
fout.close();
}