Cod sursa(job #3188459)

Utilizator AlessiaFrunzaAlessia Frunza AlessiaFrunza Data 2 ianuarie 2024 23:43:51
Problema Ciclu Eulerian Scor 50
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 2.3 kb
#include <iostream>
#include <fstream>
#include <vector>
#include <stack>
#include <unordered_map>
#include <algorithm>

using namespace std;

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

struct hash_pair {
    template <class T1, class T2>
    size_t operator () (const pair<T1, T2>& p) const {
        auto hash1 = hash<T1>{}(p.first);
        auto hash2 = hash<T2>{}(p.second);
        return hash1 ^ hash2;
    }
};

unordered_map<pair<int, int>, int, hash_pair> muchii_sterse;

void sterge_muchie(int u, int v) {
    pair<int,int> muchie = make_pair(min(u, v), max(u, v));
    muchii_sterse[muchie]--;
}

bool este_muchie_stearsa(int u, int v) {
    pair<int,int> muchie = make_pair(min(u, v), max(u, v));
    return muchii_sterse[muchie] == 0;
}

vector<int> gaseste_ciclu_eulerian(int nod_start, vector<vector<int>>& lista_vecini) {
    vector<int> ciclu;
    stack<int> stiva;

    stiva.push(nod_start);

    while (!stiva.empty()) {
        int nod = stiva.top();
        if (!lista_vecini[nod].empty()) {
            int vecin = lista_vecini[nod].back();
            lista_vecini[nod].pop_back();

            auto it = find(lista_vecini[vecin].begin(), lista_vecini[vecin].end(), nod);
            if (it != lista_vecini[vecin].end()) {
                lista_vecini[vecin].erase(it);
            }

            if (!este_muchie_stearsa(nod, vecin)) {
                sterge_muchie(nod, vecin);
                stiva.push(vecin);
            }
        } else {
            ciclu.push_back(nod);
            stiva.pop();
        }
    }

    return ciclu;
}

int main() {
    int numar_noduri, numar_muchii;
    fin >> numar_noduri >> numar_muchii;
    vector<vector<int>> lista_vecini(numar_noduri + 1);

    for (int i = 0; i < numar_muchii; i++) {
        int nod1, nod2;
        fin >> nod1 >> nod2;
        lista_vecini[nod1].push_back(nod2);
        lista_vecini[nod2].push_back(nod1);
        muchii_sterse[{min(nod1, nod2), max(nod1, nod2)}]++;
    }

    for (int i = 1; i <= numar_noduri; i++) {
        if (lista_vecini[i].size() % 2 == 1) {
            fout << "-1" << endl;
            return 0;
        }
    }

    vector<int> ciclu_eulerian = gaseste_ciclu_eulerian(1, lista_vecini);

    for (size_t i = 0; i < ciclu_eulerian.size() - 1; i++) {
        fout << ciclu_eulerian[i] << " ";
    }

    return 0;
}