Pagini recente » Cod sursa (job #2604249) | Cod sursa (job #2965446) | Cod sursa (job #2455605) | Cod sursa (job #42023) | Cod sursa (job #2795453)
#include <fstream>
#include <vector>
#include <queue>
#include <stack>
#include <iostream>
using namespace std;
const int noduriMAX = 100001;
class Graf
{
private:
int nrNoduri;
int nrMuchii;
int plecareBFS;
vector <vector<int>> adiacenta;
void Tarjan(int nod, int nrPasi[], int minimPasi[],
stack<int>* st, bool inSt[], vector<vector<int>>& afisare);
public:
void GrafNeorientat(string fisier);
void GrafOrientat(string fisier);
void DFS(int start, bool vizitat[]);
void NumaraCompCnx();
void citireBFS();
void BFS();
void CTC();
};
void Graf::GrafNeorientat(string fisier)
{
ifstream in(fisier);
in >> nrNoduri >> nrMuchii;
int start;
int capat;
adiacenta.resize(nrNoduri + 1);
for (int i = 0; i < nrMuchii; ++i)
{
in >> start >> capat;
adiacenta[start].push_back(capat);
adiacenta[capat].push_back(start);
}
in.close();
}
void Graf::GrafOrientat(string fisier)
{
ifstream in(fisier);
in >> nrNoduri >> nrMuchii;
int start;
int capat;
adiacenta.resize(nrNoduri + 1);
for (int i = 0; i < nrMuchii; ++i)
{
in >> start >> capat;
adiacenta[start].push_back(capat);
}
in.close();
}
void Graf::DFS(int start, bool vizitat[])
{
vizitat[noduriMAX] = { false };
vizitat[start] = true;
for (int vecin : adiacenta[start])
{
if (!vizitat[vecin])
DFS(vecin, vizitat);
}
}
void Graf::NumaraCompCnx()
{
ofstream out("dfs.out");
int nrCompCnx = 0;
bool vizitat[noduriMAX] = { false };
for (int i = 1; i <= nrNoduri; ++i)
{
if (!vizitat[i])
{
DFS(i, vizitat);
nrCompCnx++;
}
}
out << nrCompCnx;
out.close();
}
void Graf::citireBFS()
{
ifstream in("bfs.in");
in >> nrNoduri >> nrMuchii >> plecareBFS;
int start;
int capat;
adiacenta.resize(nrNoduri + 1);
for (int i = 0; i < nrMuchii; ++i)
{
in >> start >> capat;
adiacenta[start].push_back(capat);
}
in.close();
}
void Graf::BFS()
{
queue <int> coadaBFS;
int distanta[noduriMAX] = { 0 };
ofstream out("bfs.out");
int copiePlecareBFS = plecareBFS;
bool vizitat[noduriMAX] = { false };
vizitat[copiePlecareBFS] = true;
coadaBFS.push(copiePlecareBFS);
while (!coadaBFS.empty())
{
copiePlecareBFS = coadaBFS.front();
coadaBFS.pop();
for (int vecin : adiacenta[copiePlecareBFS])
if (!vizitat[vecin])
{
vizitat[vecin] = true;
distanta[vecin] = distanta[copiePlecareBFS] + 1;
coadaBFS.push(vecin);
}
}
for (int i = 1; i <= nrNoduri; ++i)
{
if (!vizitat[i])
out << -1 << " ";
else
out << distanta[i] << " ";
}
out.close();
}
void Graf::Tarjan(int nod, int nrPasi[], int minimPasi[], stack<int>* st, bool inSt[], vector<vector<int>>& afisare)
{
static int pas = 0;
nrPasi[nod] = minimPasi[nod] = ++pas;
st->push(nod);
inSt[nod] = true;
for (int vecin : adiacenta[nod])
{
if (nrPasi[vecin] == -1)
{
Tarjan(vecin, nrPasi, minimPasi, st, inSt, afisare);
minimPasi[nod] = min(minimPasi[nod], minimPasi[vecin]);
}
else if (inSt[vecin] == true)
minimPasi[nod] = min(minimPasi[nod], nrPasi[vecin]);
}
if (minimPasi[nod] == nrPasi[nod])
{
vector <int> auxAfisare;
while (st->top() != nod)
{
auxAfisare.push_back(st->top()); //?
inSt[st->top()] = false;
st->pop();
}
auxAfisare.push_back(st->top());
inSt[st->top()] = false;
st->pop();
afisare.push_back(auxAfisare);
}
}
void Graf::CTC()
{
int* nrPasi = new int[nrNoduri + 1];
int* minimPasi = new int[nrNoduri + 1];
bool* inSt = new bool[nrNoduri + 1];
stack<int>* st = new stack<int>();
vector < vector<int>> afisare;
for (int i = 1; i <= nrNoduri; i++)
{
nrPasi[i] = -1;
minimPasi[i] = -1;
inSt[i] = false;
}
for (int i = 1; i <= nrNoduri; i++)
if (nrPasi[i] == -1)
Tarjan(i, nrPasi, minimPasi, st, inSt, afisare);
ofstream out("ctc.out");
out << afisare.size() << "\n";
for (int i = 0; i < afisare.size(); ++i)
{
for (int j = 0; j < afisare[i].size(); ++j)
out << afisare[i][j] << " ";
out << "\n";
}
out.close();
}
int main()
{
Graf g;
g.GrafOrientat("ctc.in");
g.CTC();
return 0;
}