Mai intai trebuie sa te autentifici.
Cod sursa(job #2928454)
Utilizator | Data | 22 octombrie 2022 22:41:03 | |
---|---|---|---|
Problema | Componente tare conexe | Scor | 100 |
Compilator | cpp-64 | Status | done |
Runda | Arhiva educationala | Marime | 3.15 kb |
#include <bits/stdc++.h>
using namespace std;
ifstream fin("ctc.in");
ofstream fout("ctc.out");
class Graf {
public:
int nrNoduri, nrMuchii;
int nrCompConexe = 0;
vector <vector<int>> listaAdiacenta; //memorez graful
vector <int> nodViz; //aici marchez nodurile vizitate
vector <int> nodMin; // pentru nod = i, nodMin[i] retine val min pe care l are un vecin al lui i din aceeasi comp
vector <int> nodStiva; //nodStiva[i] retine daca nodul i se afla pe stiva
deque <int> stiva; //pe stiva se mem nodurile care ar putea fi in aceeasi comp conexa cu nodul curent
vector <vector<int>> componente; //retine comp conexe
//constructor pt graf
Graf (int nrNoduriNou, int nrMuchiiNou){
this->nrNoduri = nrNoduriNou;
this->nrMuchii = nrMuchiiNou;
vector <int> v;
for(auto i = 0 ; i <= nrNoduriNou ; i++)
{
nodViz.push_back(-1);
nodMin.push_back(-1);
nodStiva.push_back(0);
listaAdiacenta.push_back(v);
}
}
void listaNoua (int nod1, int nod2)
{
listaAdiacenta[nod1].push_back(nod2);
}
void DFS (int nod);
void afisCompConexe();
};
void Graf :: DFS (int nod)
{
static int idNou = 0;
// se reitereaza nodurile
nodViz[nod] = ++idNou;
nodMin[nod] = idNou;
stiva.push_back(nod); //pun nodul curent pe stiva
nodStiva[nod] = 1; //retin ca l am pus pe stiva
//for (int & i : listaAdiacenta[nod])
for (auto i = listaAdiacenta[nod].begin(); i != listaAdiacenta[nod].end(); i++)
{
//daca nodul nu a fost vizitat, se face DFS
if (nodViz[*i] == -1)
{
DFS(*i);
nodMin[nod] = fmin(nodMin[nod], nodMin[*i]);
}
//daca nodul e pe stiva, nu se mai face DFS
else if (nodStiva[*i] == 1)
{
nodMin[nod] = fmin(nodMin[nod], nodViz[*i]);
}
}
int aux;
if(nodMin[nod] == nodViz[nod])
{
vector<int> v;
componente.push_back(v);
while(stiva.back() != nod)
{
aux = stiva.back(); //aux retine nodul curent
componente[nrCompConexe].push_back(aux); //se scot toate elementele de pe stiva pana la nodul curent inclusiv
nodStiva[aux] = 0; // se marcheaza nodurile scoase de pe stiva
stiva.pop_back();
}
aux = stiva.back();
componente[nrCompConexe].push_back(aux);
nodStiva[aux] = 0;
stiva.pop_back();
nrCompConexe++;
}
}
void Graf::afisCompConexe()
{
for (int poz = 0 ; poz < nrNoduri ; poz++)
{
if(nodViz[poz] == -1)
DFS(poz);
}
fout << nrCompConexe << "\n";
for(int i = 0 ; i < nrCompConexe ; i++)
{
for(auto poz = componente[i].begin(); poz!=componente[i].end(); poz++)
fout << *poz + 1 << " ";
fout << "\n";
}
}
int main() {
int nrNoduri, nrMuchii, nod1, nod2;
fin >> nrNoduri >> nrMuchii;
Graf gf(nrNoduri, nrMuchii);
for(int i = 0 ; i < nrMuchii ; i++)
{
fin >> nod1 >> nod2;
gf.listaNoua(nod1-1, nod2-1);
}
gf.afisCompConexe();
return 0;
}