Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- /*
- graful va fi memorat cu listele de adiacenta retinute de o matrice
- pentru a identifica componentele biconexe, vom folosi un vector care retine muchiile grafului(indiferent daca fac parte din dfs
- sau sunt muchii de intoarcere) in ordinea parcurgerii dfs. Cand identificam un punct de articulatie,
- eliminam din vector toate muchiile din componenta biconexa respectiva si le copiem intr o matrice bi ce va retine
- toate componentele biconexe
- Variabila cate retine numarul de componente biconexe, iar varf retine indicele varfului stivi
- Consider pentru simplitate nodul 1 ca fiind de start in dfs
- */
- #include <fstream>
- #include<vector>
- #include<algorithm>
- #define dim 200005
- using namespace std;
- struct muchie
- {
- int fiu, tata;
- };
- muchie S[dim];
- vector<int>a[dim];
- vector<vector <int> >bi;
- int ord[dim],lowLink[dim],cate,nrOrd,varf;
- int n,m;
- void citire()
- {
- int i,j,k,x,y;
- ifstream fin("biconex.in");
- fin>>n>>m;
- for(k=1;k<=m;k++)
- {
- fin>>x>>y;
- a[x].push_back(y);
- a[y].push_back(x);
- }
- fin.close();
- }
- void dfs(int nodCurr, int nodTata)
- {
- //nodCurr este nodul curent, iar nodTata este nodul lui parinte
- int i,nod,x,y;
- muchie h;
- //cand se ajunge aici crestem numarul de ordine din dfs si il atribuim si lui ord si lui lowLink
- nrOrd++;
- ord[nodCurr]=lowLink[nodCurr]=nrOrd;
- //i este variabila de parcurgere a listei unui nod
- //nod este nodul adiacent lui nodCurr
- //parcurg lista de adiacenta a nodului nodCurr
- for(i=0;i<a[nodCurr].size();i++)
- {
- nod=a[nodCurr][i];
- //daca`nodul este chiar parintele nu ne intereseaza
- if(nod==nodTata)
- continue;
- //daca nod nu a mai fost vizitat
- if(ord[nod]==-1)
- {
- //introduc in S muchia (nod,nodCurr)
- h.tata=nodCurr;
- h.fiu=nod;
- varf++;S[varf]=h;
- //reapelez functia pentru nod si nodCurr care va deveni nodTata
- dfs(nod,nodCurr);
- //la derecursivitate
- //calculez minimul dintre lowLink de extremitatile muchiei nodCurr, nod
- lowLink[nodCurr]=min(lowLink[nodCurr],lowLink[nod]);
- //daca nodCurr este punct de articulatie, am gasit o componenta biconexa
- //formata din toate muchiile stivei pana la intalnirea muchiei [nodCurr,nod]
- if(lowLink[nod]>=ord[nodCurr])
- {
- cate++;
- //copii in matricea bi, componenta conexa din stiva
- //vectorul aux retine acea componenta luata din S
- vector<int>aux;
- do
- {
- x=S[varf].fiu;
- y=S[varf].tata;
- varf--;
- aux.push_back(x);
- aux.push_back(y);
- }
- while(y!=nodCurr || x!=nod);
- bi.push_back(aux);
- }
- }
- else
- {
- //in acez caz nodCurr a mai fost vizitat, verific daca este o muchie de intoarcere si actualizez lowLink
- if(nodCurr!=nodTata)
- lowLink[nodCurr]=min(lowLink[nodCurr],ord[nod]);
- }
- }
- }
- int main()
- {
- ofstream fout("biconex.out");
- citire();
- int i,j;
- for(i=1;i<=n;i++)
- ord[i]=lowLink[i]=-1;
- //initializez vectorul S cu nodul de pornire, el nu are tata, consider -1
- S[0].fiu=1;
- S[0].tata=-1;
- dfs(1,0);
- fout<<cate<<"\n";
- //afisez fiecare linie a lui bi
- for(i=0;i<bi.size();i++)
- {
- //in fiecare linie unele noduri apar de mai multe ori si sunt in ordine inversa
- //sortez si elimim duplicatele
- sort(bi[i].begin(), bi[i].end());
- bi[i].erase(unique(bi[i].begin(), bi[i].end()), bi[i].end());
- for(j=0;j<bi[i].size();j++)
- fout<<bi[i][j]<<" ";
- fout<<"\n";
- }
- return 0;
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement