Pagini recente » Cod sursa (job #2180130) | Cod sursa (job #1206616) | Cod sursa (job #1726852) | Cod sursa (job #10189) | Cod sursa (job #2785126)
#include <iostream>
#include <fstream>
#include <vector>
#include <queue>
#include <unordered_set>
#include <stack>
//std::ifstream f("graful.txt");
//std::ofstream g("graful.out");
std::ifstream f("biconex.in");
std::ofstream g("biconex.out");
// Obs: graful initial este conex
int start = 0, contor; // contorul il vom folosi in mai multe probleme; start va aparea eventual ca nod de start
typedef std::stack< std::pair <int, int > > stackpair;
typedef std::unordered_set< int > multime;
typedef std::vector< std::vector < int > > vector_vectori;
class graf
{
int nrvf, nrmuchii;
std::vector<int>* vecini;
public:
graf(bool orientat);
void verifvecini();
void BFS();
void DFS(int nod, bool* viz);
void cadruDFS();
void biconexe(int nod, int tata, bool* viz, multime* wayback, stackpair& muchiiviz, vector_vectori& comp_biconexe);
void cadru_biconexe();
~graf()
{
delete []vecini;
}
};
graf::graf(bool orientat)
{
f >> nrvf >> nrmuchii;
if(start == 1) // daca avem de citit un nod de start...
f >> start;
vecini = new std::vector<int>[nrvf + 1];
if (orientat == true)
for (int i = 0; i < nrmuchii; i++)
{
int x, y;
f >> x >> y;
vecini[x].push_back(y);
}
else
for (int i = 0; i < nrmuchii; i++)
{
int x, y;
f >> x >> y;
vecini[x].push_back(y);
vecini[y].push_back(x);
}
}
void graf::verifvecini()
{
for (int i = 1; i <= nrvf; i++)
{
std::cout << "\n vecinii lui " << i << " : ";
for (unsigned int j = 0; j < vecini[i].size(); j++)
std::cout << vecini[i][j] << " ";
}
}
void graf::BFS()
{
int* dist = new int[nrvf + 1]{ 0 }; // initializam distantele cu 0 (le decrementam ulterior)
std::queue <int> qBFS; // coada pt BFS
qBFS.push(start);
dist[start] = 1;
while (!qBFS.empty())
{
const int nod = qBFS.front();
for (unsigned int i = 0; i < vecini[nod].size(); i++)
{
const int nod_urm = vecini[nod][i];
if (dist[nod_urm] == 0)
{
qBFS.push(nod_urm);
dist[nod_urm] = dist[nod] + 1;
}
}
qBFS.pop();
}
for (int i = 1; i <= nrvf; i++)
g << dist[i] - 1 << " ";
delete [] dist;
}
void graf::DFS(int nod, bool* viz)
{
viz[nod] = true;
for (unsigned int i = 0; i < vecini[nod].size(); i++)
{
const int nod_urm = vecini[nod][i];
if (!viz[nod_urm])
DFS(nod_urm, viz);
}
}
void graf::cadruDFS()
{
contor = 0;
bool* viz = new bool[nrvf + 1]{ 0 };
for (int i = 1; i <= nrvf; i++)
if( ! viz[i] )
{
contor++;
DFS(i, viz);
}
g << contor;
delete[]viz;
}
void graf::biconexe(int nod, int tata, bool* viz, multime* wayback, stackpair& muchiiviz, vector_vectori& comp_biconexe)
{
viz[nod] = true;
for (unsigned int i = 0; i < vecini[nod].size(); i++)
{
const int nod_urm = vecini[nod][i];
if (viz[nod_urm])
{
if (nod_urm != tata and nod_urm != nod)
{
wayback->insert(nod_urm);
for(unsigned int i = 0; i < vecini[nod_urm].size(); i ++ )
if (vecini[nod_urm][i] == nod)
{
vecini[nod_urm][i] = nod_urm;
break;
}
}
}
else
{
muchiiviz.push({ nod, nod_urm });
multime* wayback_fiu = new multime;
biconexe(nod_urm, nod, viz, wayback_fiu, muchiiviz, comp_biconexe);
wayback_fiu->erase(nod);
if (wayback_fiu->size() == 0)
{
contor++;
std::vector< int > aux;
comp_biconexe.push_back(aux);
while (muchiiviz.top().first != nod)
{
comp_biconexe.back().push_back(muchiiviz.top().second);
muchiiviz.pop();
}
comp_biconexe.back().push_back(muchiiviz.top().second);
comp_biconexe.back().push_back(muchiiviz.top().first);
muchiiviz.pop();
}
else
wayback->insert(wayback_fiu->begin(), wayback_fiu->end());
delete wayback_fiu;
}
}
}
void graf::cadru_biconexe()
{
contor = 0;
vector_vectori comp_biconexe; // solutia, de forma unui vector cu alti vectori ce reprezinta componentele biconexe
bool* viz = new bool[nrvf + 1]{ 0 }; // nodurile vizitate deja
stackpair muchiiviz; // stiva de muchii vizitate
multime* setgol = new multime; // un set "wayback" pe care il pasez fiului pentru a-mi returna caile de intoarcere disponibile
biconexe(1, -1, viz, setgol, muchiiviz, comp_biconexe);
delete setgol;
g << contor << "\n";
for (unsigned int i = 0; i < comp_biconexe.size(); i++)
{
for (unsigned int j = 0; j < comp_biconexe[i].size(); j++) {
g << comp_biconexe[i][j] << " ";
}
g << "\n";
}
}
int main()
{
start = 0; // afirmam daca citim si un nod de start;
graf g(false);
g.cadru_biconexe();
return 0;
}