Pagini recente » Cod sursa (job #2887422) | Cod sursa (job #1676209) | Cod sursa (job #2716722) | Cod sursa (job #2161460) | Cod sursa (job #2930021)
#include <iostream>
#include <fstream>
#include <vector>
#include <stack>
using namespace std;
// Folosim algoritmul lui tarjan pentru a gasi componentele tare conexe
// Se parcurg nodurile prin dfs si le sunt atribuite un index si o valoare lowlink egala initial cu indexul
// Valoarea lowlink reprezinta cel mai inapoiat nod la care poate ajunge nodul respectiv
// Daca mai multe noduri au aceeasi valoare lowlink, atunci ele fac parte dintr-o componenta tare conexa
// Se pastreaza o stiva pentru a verifica daca nodurile fac parte din aceeasi parcurgere si daca le pot fi egalate valorile lowlink
// La intoarcerea din dfs calculam minimul valorilor lowlink ale unui nod cu nodul vecin daca nodul vecin este in stiva
// Golim stiva daca indexul este egal cu valoarea lowlink pentru ca inseamna ca s-a gasit inceputul componentei tare conexe
// Complexitate timp : O(N)
// Complexitate spatiu : O(N)
ifstream f("ctc.in");
ofstream g("ctc.out");
vector<vector<int>> adj_list;
vector<int> indx; //retine indexul atribuit fiecarui nod in urma parcurgerii DFS
vector<int> lowlink; // Indexul cel mai mic care poate fi accesat din nodul curent (lowlink value)
//Stiva care va verifica daca nodurile sunt in procesul de parcurgere.
// Daca un nod u intalneste un nod v care este in stiva, atunci valoarea lowlink poate fi atribuita ca minimul valorilor lowlink a celor 2 noduri
vector <bool> onStack;
stack <int> st;
int id = 0; // Id-ul fiecarui nod
int sccCount = 0; //contorizeaza componentele tare conexe
vector<vector<int>> scc; //memoreaza componentele tare conexe
//algoritmul lui tarjan
void dfs(int node){
st.push(node);
onStack[node] = true;
indx[node] = lowlink[node] = ++id;
//vizitam toti vecinii nodului si la intoarcere calculam minimul valorilor lowlink ale nodului cu nodul vecin daca nodul vecin este in stiva
for(auto x : adj_list[node]){
if(indx[x] == -1)
dfs(x);
if(onStack[x])
lowlink[node] = min(lowlink[node], lowlink[x]);
}
// Golim stiva daca am ajuns la inceputul unei componente tare conexe ( Daca indexul este egal cu valoarea lowlink )
if(indx[node] == lowlink[node]){
vector<int> currentCtc;
int nod = st.top();
while(nod != node){
st.pop();
onStack[nod] = false;
lowlink[nod] = indx[node];
currentCtc.push_back(nod);
nod = st.top();
}
st.pop();
currentCtc.push_back(node);
scc.push_back(currentCtc);
onStack[node] = false;
sccCount++;
}
}
int main(){
int n,m,x,y;
f >> n >> m;
adj_list.resize(n+1);
for(int i = 0; i < m; ++i){
f >> x >> y;
adj_list[x].push_back(y);
}
indx = vector<int>(n + 1,-1);
lowlink = vector<int>(n + 1,-1);
onStack = vector<bool>(n + 1,false);
for(int i = 1; i < n+1; ++i)
if(indx[i] == -1)
dfs(i);
g<<sccCount<<"\n";
for(auto x: scc) {
for (auto y: x)
g << y << " ";
g<<"\n";
}
}