Cod sursa(job #2820760)

Utilizator ptr22222Petru Popescu ptr22222 Data 21 decembrie 2021 14:40:14
Problema Ciclu Eulerian Scor 80
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 3.92 kb
#include <iostream>
#include <fstream>
#include <vector>
#include <queue>
#include <stack>
#include <algorithm>

using namespace std;

ifstream in("ciclueuler.in");
ofstream out("ciclueuler.out");

const int inf = 1<<30;

class Graf
{
private:
    static const int nmax = 100001;
    static const int mmax = 500001;
    bool orientat;
    int nrNoduri;
    vector <int> listaAdiacenta[nmax];
    vector <pair <int, int>> listaAdiacentaCost[nmax];
public:
    Graf(int nrNoduri = 0, bool orientat = false);
    void adaugaMuchie(int, int);
    void adaugaMuchieCost(int, int, int);
    void citireMuchii(int);
    void citireMuchiiCost(int);
    vector<int> BFS(int);
    void DFS(int, bool*);
    int nrComponenteConexe();
    void DFSStiva(int nodcurent, bool *, stack<int> &);
    void sortareTopologica();
    void TarjanCTC(int&, int, int*, int*, bool*, stack <int> &, vector<vector<int>> &);
    void CTC();
    void TarjanBC(int&, int, int, int*, int*, stack <int>&, vector<vector<int>>&);
    void BC();
    void TarjanMC(int&, int, int, int*, int*, vector<pair<int,int>>&);
    void MC();
    vector <int> citireHakimi();
    bool Hakimi(vector <int>);
    vector <int> Dijkstra(int);
    pair<int, vector <pair <int, int>>> Prim(int);
    vector <int> BellmanFord(int);
    void reuniune(int, int, vector<int>&, vector<int>&);
    int gasire(int, vector<int>&);
    void verifica(int, int, vector<int>&);
    void paduri();
    void RoyFloyd(int[][nmax]);
    void rezolvareRoyFloyd();
    int diametru();
    bool BFSFMax(int**, int*, int, int);
    int EdmondsKarp(int**, int, int);
    void citireAfisareEdmondsKarp(int, int, int);
    void cicluEuler(int, bool*, vector<int>&);
    void rezolvareEuler();
};

Graf :: Graf(int nrNoduri, bool orientat) : nrNoduri(nrNoduri), orientat(orientat)
{
    this->nrNoduri = nrNoduri;
    this->orientat = orientat;
}

void Graf:: adaugaMuchie(int nod1, int nod2)
{
    listaAdiacenta[nod1].push_back(nod2);
}

void Graf::adaugaMuchieCost(int nod1, int nod2, int cost)
{
    listaAdiacentaCost[nod1].push_back(make_pair(nod2, cost));
}

void Graf::citireMuchii(int nrMuchii)
{
    int nod1, nod2;
    for(int i = 0; i < nrMuchii; i++)
    {
        in >> nod1 >> nod2;
        listaAdiacenta[nod1].push_back(nod2);
        if(!orientat)
        {
            listaAdiacenta[nod2].push_back(nod1);
        }
    }
}

void Graf::citireMuchiiCost(int nrMuchii)
{
    int nod1, nod2, cost;
    for(int i = 0; i < nrMuchii; i++)
    {
        in >> nod1 >> nod2 >> cost;
        adaugaMuchieCost(nod1, nod2, cost);
        if(!orientat)
        {
            adaugaMuchieCost(nod2, nod1, cost);
        }
    }
}

void Graf::cicluEuler(int nodStart, bool *vizitat, vector<int>& ciclu)
{
    stack <int> stiva;
    stiva.push(nodStart);
    while(!stiva.empty())
    {
        int nodCurent = stiva.top();
        if(!listaAdiacentaCost[nodCurent].empty())
        {
            int vecin = listaAdiacentaCost[nodCurent].back().first;
            int nrMuchie = listaAdiacentaCost[nodCurent].back().second;
            listaAdiacentaCost[nodCurent].pop_back();
            if(!vizitat[nrMuchie])
            {
                vizitat[nrMuchie] = true;
                stiva.push(vecin);
            }
        }
        else
        {
            ciclu.push_back(nodCurent);
            stiva.pop();
        }
    }
}

void Graf::rezolvareEuler()
{
    bool vizitat[mmax];
    vector <int> ciclu;
    for(int i = 0; i <= nrNoduri; i++)
    {
        if(listaAdiacentaCost[i].size() & 1)
        {
            out << "-1\n";
            return;
        }
    }
    cicluEuler(1, vizitat, ciclu);
    for(int i = 0; i < ciclu.size() - 1; i++)
    {
        out << ciclu[i] << " ";
    }
}

int main()
{
    int n, m;
    in >> n >> m;
    Graf g(n, false);
    int nod1, nod2;
    for(int i = 0; i < m; i++)
    {
        in >> nod1 >> nod2;
        g.adaugaMuchieCost(nod1, nod2, i);
        g.adaugaMuchieCost(nod2, nod1, i);
    }
    g.rezolvareEuler();
    return 0;
}