Cod sursa(job #2815518)

Utilizator redikusTiganus Alexandru redikus Data 9 decembrie 2021 19:19:53
Problema Ciclu Eulerian Scor 80
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 3.46 kb
#include <iostream>
#include <fstream>
#include <vector>
#include <queue>
#include <stack>
#include <unordered_set>
#include <unordered_map>
#include <string>
#include <algorithm>

using namespace std;

// Clasa pentru graf
class graf {

protected:
    int noduri, muchii;
    vector < vector < int >> adiacenta;

public:
    // Constructor cu matrice de adiacenta data
    graf(vector < vector < int >> listaAdiacenta, int noduri, int muchii): adiacenta(listaAdiacenta), noduri(noduri), muchii(muchii) {};

    // Constructor fara matrice de adiacenta, se cu initalizeaza una goala
    graf(int noduri, int muchii): adiacenta(noduri + 1), noduri(noduri), muchii(muchii) {};

    vector < int > bfs(int);
    int dfs();

};

// Clasa pentru graf neorientat
class graf_neorientat : public graf{
private:
    void dfsbiconex(int, vector < int >&, vector < int >&, stack < pair < int, int >>&, int&, vector < string >&);
    void dfsCriticalConnections(int tata, vector < int >&, vector < int >&, int&, vector < vector < int >>&, vector < int >&);
    int darbbfs(int, int&);

public:
    graf_neorientat(vector < vector < int >> listaAdiacenta, int noduri, int muchii): graf(listaAdiacenta, noduri, muchii) {};
    graf_neorientat(int noduri, int muchii): graf(noduri, muchii) {};

    friend istream& operator>>(istream&, graf_neorientat&);
    vector < string > biconex();
    vector < vector < int >> criticalConnections();
    int darb();
    bool checkEuler(int &start);
    vector<int> euler(int start);

};

// Citire pentru graf neorientat
istream& operator>>(istream& in, graf_neorientat& g) {
    for (int i = 0; i < g.muchii; i++) {
        int aux1, aux2;
        in >> aux1 >> aux2;
        g.adiacenta[aux1].push_back(aux2);
        g.adiacenta[aux2].push_back(aux1);
    }
    return in;
}

// Functie care verifica daca un graf neorientat poate fi euler
bool graf_neorientat::checkEuler(int &start){
    for (int i = 1; i<adiacenta.size(); i++) {
        if (adiacenta[i].size() % 2 != 0) {
            return 0;
        }
    }
    return 1;
}

// Functie care returneaza ciclul euler al unui graf eulerian
vector<int> graf_neorientat :: euler(int start)
{
    stack<int> curent;
    vector<int> raspuns;

    curent.push(start);

    while (!curent.empty()) {
        int nod = curent.top();
        if (adiacenta[nod].size()) {
            int nod1 = adiacenta[nod].back();
            curent.push(nod1);
            adiacenta[nod].pop_back();
            int i;
            for (i = 0; i < adiacenta[nod1].size(); i++) {
                if (adiacenta[nod1][i] == nod) {
                    break;
                }
            }
            adiacenta[nod1].erase(adiacenta[nod1].begin() + i);
        }
        else {
            raspuns.push_back(nod);
            curent.pop();
        }
    }

    return raspuns;
}

void eulerDriver() {
    // https://infoarena.ro/problema/ciclueuler
    // Citire
    ifstream in("ciclueuler.in");
    ofstream out("ciclueuler.out");

    int n, m;
    in >> n >> m;

    graf_neorientat x(n, m);
    in >> x;
    int start = 1;

    if (!x.checkEuler(start)) {
        out << -1;
    }

    else {
        vector<int> raspuns = x.euler(1);
        for (int i = 0; i < raspuns.size() - 1; i++) {
            out << raspuns[i] << " ";
        }
    }
}

int main() {
    // Se apeleaza functia corespunzatoare problemei
    eulerDriver();
    return 0;
}