Cod sursa(job #2790869)

Utilizator Bogdan.paun50Mandresi Bogdan Bogdan.paun50 Data 29 octombrie 2021 17:59:03
Problema Ciclu Eulerian Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 2.9 kb
#include <bits/stdc++.h>
using namespace std;

const int DIM = 100005;

// in lista de vecini retin perechi de forma (vecin, indexul muchiei catre
// vecin)
int idx_muchie = 0;
vector<pair<int, int>> g[DIM];
bool deleted[5 *
             DIM];  // deleted[i] == true <=> muchia cu indexul i a fost stearsa

vector<int> sol;

int grad[DIM];
bool vis[5 * DIM];  // muchiile deja vizitate
int nr_muchii = 0;

void dfs(int nod) {
    vis[nod] = true;
    nr_muchii += (int)g[nod].size();
    for (pair<int, int> e : g[nod]) {
        if (!vis[e.first]) {
            dfs(e.first);
        }
    }
}

void euler(int nod) {
    for (int i = g[nod].size() - 1; i >= 0; --i) {
        int vecin = g[nod][i].first;
        int muchie = g[nod][i].second;
        g[nod].pop_back();  // putem deja sterge muchia din lista de vecini a
                            // lui nod
        if (!deleted[muchie]) {  // daca muchia nu a fost stearsa anterior de
                                 // vecin putem merge pe ea
            deleted[muchie] = true;
            euler(vecin);
        }
    }
    sol.push_back(nod);
}

// echivalent cu functia de mai sus dar fara recursivitate
void euler_stiva(int sursa) {
    stack<int> st;
    st.push(sursa);

    while (!st.empty()) {
        int nod = st.top();
        // determin primul vecin de la sfarsit catre care muchia nu e stearsa
        while (!g[nod].empty()) {
            pair<int, int> e = g[nod].back();
            if (!deleted[e.second]) break;
            g[nod].pop_back();
        }

        if (!g[nod].empty()) {  // daca am in ce nod sa ma duc (intru in
                                // "recursivitate")
            st.push(g[nod].back().first);
            deleted[g[nod].back().second] = true;
            g[nod].pop_back();
        } else {  // ma intorc din "recursivitate"
            sol.push_back(nod);
            st.pop();
        }
    }
}

int main() {
#ifdef LOCAL
    ifstream cin("a.in");
    ofstream cout("a.out");
#else
    ifstream cin("ciclueuler.in");
    ofstream cout("ciclueuler.out");
#endif

    int N, M;
    cin >> N >> M;
    for (int i = 1; i <= M; ++i) {
        int x, y;
        cin >> x >> y;
        idx_muchie++;  // actualizez indexul curent al muchiei
        g[x].push_back(make_pair(y, idx_muchie));
        g[y].push_back(make_pair(x, idx_muchie));

        grad[x]++;
        grad[y]++;
    }

    for (int i = 1; i <= N; ++i) {
        if (grad[i] % 2 == 1) {
            cout << "-1\n";
            return 0;
        }
    }

    // cautam un nod neizolat
    int sursa = 1;
    while (grad[sursa] == 0) sursa++;

    dfs(sursa);
    if (nr_muchii != 2 * M) {
        cout << "-1\n";
        return 0;
    }

    euler_stiva(sursa);

    sol.pop_back();  // nodul de start/end e acelasi
    for (int x : sol) {
        cout << x << " ";
    }
    cout << "\n";
}