Pagini recente » Cod sursa (job #1495950) | Cod sursa (job #2923895) | Cod sursa (job #286226) | Cod sursa (job #194998) | Cod sursa (job #2796928)
#include <iostream>
#include <fstream>
#include <vector>
#include <stack>
#include <algorithm>
using namespace std;
class Graf{
private:
int m_nrNoduri;
vector<vector<int>> m_listeAdiacenta;
vector<int> viz;
vector<int> arrivalTimes;
vector<int> lowLinkValues;
vector<vector<int>> componenteBiconexe;
stack<pair<int,int>> StivaMuchiiComponentaBiconexaCurenta;
public:
void citireGrafNeorientat(char* fisier);
void afisComponenteBiconexe(char* fisier);
void DFSBiconexe(int nodCurent, int precedent, int pas);
};
void Graf::citireGrafNeorientat(char* fisier){
ifstream f(fisier);
int nrMuchii;
f>>this->m_nrNoduri;
this->m_listeAdiacenta.resize(this->m_nrNoduri+1);
f>>nrMuchii;
for(int i=0; i<nrMuchii; i++){
int x,y;
f>>x>>y;
this->m_listeAdiacenta[x].push_back(y);
this->m_listeAdiacenta[y].push_back(x);
}
}
void Graf::DFSBiconexe(int nodCurent, int precedent, int pas){
//marcam ca vizitat nodul curent
arrivalTimes[nodCurent] = pas;
//momentan nivelul minim de intoarcere e nivelul curent, adica pasul
lowLinkValues[nodCurent] = pas;
//parcurgem vecinii nodului curent
for(int i=0; i<this->m_listeAdiacenta[nodCurent].size(); i++){
int vecinCurent = this->m_listeAdiacenta[nodCurent][i];
if(vecinCurent != precedent){
//verificam pe ce fel de muchie suntem
//daca vecinul curent a mai fost vizitat inseamna ca am dat de o muchie de intoarcere, altfel suntem pe o muchie in jos
if(arrivalTimes[vecinCurent] == -1){
//am dat de o noua muchie din componenta biconexa curenta, asa ca o adaugam in stiva
StivaMuchiiComponentaBiconexaCurenta.push(make_pair(nodCurent, vecinCurent));
//apelam DFS pentru vecinul curent
DFSBiconexe(vecinCurent, nodCurent, pas + 1);
//verificam daca atunci cand ne am dus mai departe in graf
// am dat de o muchie de intoarcere care ne duce mai sus decat ne ducea nodul acesta inainte
if(lowLinkValues[nodCurent] > lowLinkValues[vecinCurent]){
lowLinkValues[nodCurent] = lowLinkValues[vecinCurent];
}
//verificam daca am ajuns la finalul componentei biconexe
if(lowLinkValues[vecinCurent] >= arrivalTimes[nodCurent]){
//trebuie sa adaugam noua componenta biconexa in vectorul de componenete biconexe
//si sa golim stiva cu muchiile componentei biconexe curente
vector<int> aux;
int aux1, aux2;
do{
aux1 = StivaMuchiiComponentaBiconexaCurenta.top().first;
aux2 = StivaMuchiiComponentaBiconexaCurenta.top().second;
aux.push_back(aux1);
aux.push_back(aux2);
StivaMuchiiComponentaBiconexaCurenta.pop();
} while (aux1 != nodCurent || aux2 != vecinCurent);
componenteBiconexe.push_back(aux);
}
}else{
//avem o muchie de intoarcere, trebuie sa verificam daca nu cumva duce mai sus
if(lowLinkValues[nodCurent] > arrivalTimes[vecinCurent]){
lowLinkValues[nodCurent] = arrivalTimes[vecinCurent];
}
}
}
}
}
void Graf::afisComponenteBiconexe(char* fisier){
ofstream g(fisier);
this->arrivalTimes.assign(this->m_nrNoduri+1,-1);
this->lowLinkValues.resize(this->m_nrNoduri+1);
this->DFSBiconexe(1,0,0);
g<<this->componenteBiconexe.size()<<"\n";
for(int i=0; i<this->componenteBiconexe.size(); i++){
//componenteBiconexe[i].erase(unique(componenteBiconexe[i].begin(), componenteBiconexe[i].end()), componenteBiconexe[i].end());
for(int j=0; j<this->componenteBiconexe[i].size(); j++){
g<<this->componenteBiconexe[i][j]<<" ";
}
g<<"\n";
}
}
int main()
{
Graf g;
g.citireGrafNeorientat("biconex.in");
g.afisComponenteBiconexe("biconex.out");
return 0;
}