Pagini recente » Cod sursa (job #2167416) | Cod sursa (job #2533669) | Cod sursa (job #2940822) | Cod sursa (job #279304) | Cod sursa (job #3270761)
#include <iostream>
#include <vector>
#include <fstream>
#include <stack>
#include <algorithm>
void citire(std::vector<std::vector<int> > &graf, std::vector<std::vector<int> > &grafTranspus, int &n) {
std::ifstream f("ctc.in");
int i, j;
int m;
f >> n >> m;
graf.resize(n);
grafTranspus.resize(n);
while (m--) {
f >> i >> j;
graf[i - 1].push_back(j - 1);
grafTranspus[j - 1].push_back(i - 1);
}
f.close();
}
void dfs(std::vector<std::vector<int> > &graf, std::vector<bool> &viz, std::stack<int> &s, const int node) {
viz[node] = true;
for (const auto &v: graf[node])
if (!viz[v])
dfs(graf, viz, s, v);
s.push(node);
}
void kosaraju() {
// Pasul 1: citim graful G si construim G^T.
std::vector<std::vector<int> > graf, grafTranspus;
int n;
citire(graf, grafTranspus, n);
// Pasul 2: parcurgem G cu DFS si stocam varfurile intr-o stiva.
std::stack<int> s;
std::vector viz(n, false);
for (int i = 0; i < n; ++i)
if (!viz[i])
dfs(graf, viz, s, i);
// Pasul 3: parcurgem G^T cu DFS. Pentru fiecare parcurgere, stocam varfurile intr-o stiva.
std::vector<std::vector<int> > componente;
std::fill(viz.begin(), viz.end(), false);
while (!s.empty()) {
const int node = s.top();
s.pop();
std::stack<int> aux;
if (!viz[node])
dfs(grafTranspus, viz, aux, node);
if (!aux.empty()) {
std::vector<int> componenta;
while (!aux.empty()) {
const int v = aux.top();
aux.pop();
componenta.push_back(v + 1);
}
componente.push_back(componenta);
}
}
std::ofstream g("ctc.out");
g << componente.size() << "\n";
for (const auto &componenta: componente) {
for (const auto &nod: componenta)
g << nod << " ";
g << "\n";
}
g.close();
}
int main() {
// CERINTA: Se da un graf orientat. Sa se afiseze componentele tare conexe.
// COMPONENTA TARE CONEXA = intre oricare 2 varfuri din componenta respectiva exista un drum.
// Algoritmul lui Kosaraju:
// Pasul 1: Construim graful transpus G^T (arcele sunt inversate).
// Pasul 2: Parcurgem graful G cu DFS si introducem intr-o stiva fiecare varf la momentul la care este finalizat.
// (vrem o ordonare descrescator a varfurilor dupa timpul de finalizare).
// Pasul 3: Parcurgem graful G^T cu DFS considerand varfurile in ordinea in care sunt extrase din stiva.
kosaraju();
return 0;
}