Pagini recente » Cod sursa (job #2114053) | Cod sursa (job #1446515) | Cod sursa (job #1282459) | Cod sursa (job #256179) | Cod sursa (job #2928287)
/*
Folosim Algoritmul lui Kosaraju:
- facem o parcurgere DFS pentru a afla nr de componente conexe
(pastram nodul intr-o stiva dupa ce i-am vizitat vecinii)
- facem si o a doua parcurgere DFS pe graful transpus pentru a afla noile componentele
conexe (scot cate un nod de pe stiva si daca nu a fost vizitat ii aplic acest DFS_transpus)
--> algoritmul foloseste doua parcurgeri in inaltime
--------> Complexitatea = O(n+m)
*/
#include <iostream>
#include <fstream>
#include <vector>
using namespace std;
ifstream fin("ctc.in");
ofstream fout("ctc.out");
int n, m;
int nr_componente_tare_conexe;
vector < vector <int>> adj;
vector < vector <int>> adj_transpus;
vector < vector <int>> componente;
vector <int> mystack;
vector <int> level;
void Citire()
{
int i;
fin >> n >> m;
adj.resize(n+1);
adj_transpus.resize(n+1);
for(i = 1; i <= m; i++)
{
int x, y;
fin >> x >> y;
adj[x].push_back(y);
adj_transpus[y].push_back(x);
}
}
void DFS(int nod)
{
for(int i = 0; i < adj[nod].size(); i++)
{
if(level[adj[nod][i]] == 0)
{
level[adj[nod][i]] = 1;
DFS(adj[nod][i]);
}
}
mystack.push_back(nod);
}
void DFS_transpus(int nod)
{
componente[nr_componente_tare_conexe].push_back(nod);
level[nod] = 2;
for(int i = 0; i < adj_transpus[nod].size(); i++)
{
if(level[adj_transpus[nod][i]] == 1)
DFS_transpus(adj_transpus[nod][i]);
}
}
void Afisare()
{
fout << nr_componente_tare_conexe << "\n";
for(int i = 1; i <= nr_componente_tare_conexe; i++)
{
for(int j = 0; j < componente[i].size(); j++)
fout << componente[i][j] << " ";
fout << "\n";
}
}
int main()
{
int i, node;
Citire();
level.resize(n+1);
componente.resize(n+1);
for(i = 1; i <= n; i++)
level[i] = 0;
for(i = 1; i <= n; i++)
if(level[i] == 0)
{
level[i] = 1;
DFS(i);
}
while(mystack.empty() == 0)
{
node = mystack.back();
mystack.pop_back();
if(level[node] == 1)
{
nr_componente_tare_conexe++;
DFS_transpus(node);
}
}
Afisare();
return 0;
}