Pagini recente » Cod sursa (job #826528) | Cod sursa (job #1951464) | Cod sursa (job #2058619) | Cod sursa (job #1604082) | Cod sursa (job #2823079)
#include <iostream>
#include <fstream>
#include <algorithm>
#include <vector>
#include <queue>
#include <stack>
using namespace std;
class Disjoint_set
{
int noduri;
vector<int>tata; // vector in care sunt stocati reprezentantii componentelor/arborilor(reprezentantul arborelui este radacina sa)
vector<int>h; // vector in care este stocata inaltimea arborilor
public:
Disjoint_set(int n);
void initializare(); // initializarea vectorului de tati/reprezentanti si a vectorului de inaltimi
int reprezentant(int varf); // determinarea radacinii arborelui care contine varf
void reuneste(int varf1, int varf2); // reuniunea componentelor care contin varf1 si varf2
void solve_paduri_de_multimi_disjuncte(ifstream& f, ofstream& o);
};
Disjoint_set::Disjoint_set(int n)
{
noduri = n;
}
void Disjoint_set::initializare()
{
tata.resize(noduri + 1, 0);
h.resize(noduri + 1, 0);
}
int Disjoint_set::reprezentant(int varf)
{
while (tata[varf] != 0)
varf = tata[varf];
return varf;
}
void Disjoint_set::reuneste(int varf1, int varf2)
{
int rv1, rv2;
rv1 = reprezentant(varf1);
rv2 = reprezentant(varf2);
if (h[rv1] > h[rv2]) // reuniunea se face in functie de inaltimea arborilor(arborele cu inaltime mai mica devine subarbore al radacinii celuilalt arbore)
tata[rv2] = rv1;
else
{
tata[rv1] = rv2;
if (h[rv1] == h[rv2])
h[rv2] ++;
}
}
void Disjoint_set::solve_paduri_de_multimi_disjuncte(ifstream& f, ofstream& o)
{
int nr_operatii;
f >> nr_operatii;
initializare();
for (int i = 0; i < nr_operatii; i++)
{
int cod, x, y;
f >> cod >> x >> y;
if (cod == 1)
reuneste(x, y);
else
{
if (reprezentant(x) == reprezentant(y))
o << "DA" << "\n";
else
o << "NU" << "\n";
}
}
}
class Graf
{
int noduri, muchii;
bool ciclu_eulerian(vector<vector<int>>& vecini, vector<int>& grade, vector<int>& componente_ciclu_eulerian);
public:
Graf(int n, int m);
void solve_ciclu_eulerian(ifstream& f, ofstream& o);
};
Graf::Graf(int n, int m)
{
noduri = n;
muchii = m;
}
bool Graf::ciclu_eulerian(vector<vector<int>>& vecini, vector<int>& grade, vector<int>& componente_ciclu_eulerian)
{
for (int i = 1; i <= noduri; i++) // verific daca avem noduri de grad impar
if (grade[i] % 2)
return 0;
int varf = 1; // cautam primul nod cu grad != 0
while (varf <= noduri && grade[varf] == 0)
varf++;
if (varf == noduri + 1) // toate varfurile au gradul 0
return 1;
stack<int>st;
st.push(varf);
while (st.size())
{
varf = st.top();
if (vecini[varf].size() == 0)
{
componente_ciclu_eulerian.push_back(varf);
st.pop();
}
else
{
int varf2 = vecini[varf][0];
vecini[varf].erase(vecini[varf].begin());
for (int j = 0; j < vecini[varf2].size(); j++)
if (vecini[varf2][j] == varf)
{
vecini[varf2].erase(vecini[varf2].begin() + j);
break;
}
st.push(varf2);
}
}
for (int i = 1; i <= noduri; i++)
if (vecini[i].size())
return 0;
}
void Graf::solve_ciclu_eulerian(ifstream& f, ofstream& o)
{
vector<vector<int>>vecini(noduri + 1); // liste de adiacenta
vector<int>grade(noduri + 1, 0); // vector in care sunt stocate gradele varfurilor
vector<int>componente_ciclu_eulerian; // vector in care sunt stocate extremitatile muchiilor ce alcatuiesc ciclul eulerian(acolo unde exista unul)
for (int i = 0; i < muchii; i++)
{
int x, y; // extremitatile unei muchii
f >> x >> y;
vecini[x].push_back(y);
vecini[y].push_back(x);
grade[x]++;
grade[y]++;
}
if (ciclu_eulerian(vecini, grade, componente_ciclu_eulerian))
for (int i = 0; i < componente_ciclu_eulerian.size() - 1; i++)
o << componente_ciclu_eulerian[i] << " ";
//cout << 1;
else
o << -1;
}
int main()
{
ifstream f("ciclueuler.in");
ofstream o("ciclueuler.out");
int noduri, muchii;
f >> noduri >> muchii;
Graf g(noduri, muchii);
g.solve_ciclu_eulerian(f, o);
return 0;
}