Cod sursa(job #3338004)

Utilizator Tudor28Ceclan Tudor Tudor28 Data 31 ianuarie 2026 10:09:35
Problema Ciclu Eulerian Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 2.66 kb
#include <bits/stdc++.h>
using namespace std;

int main()
{
    ios::sync_with_stdio(false);
    cin.tie(nullptr);

    freopen("ciclueuler.in", "r", stdin);
    freopen("ciclueuler.out", "w", stdout);

    int N, M;
    cin >> N >> M;

    vector<vector<pair<int, int>>> g(N + 1);
    vector<int> deg(N + 1, 0);

    for (int id = 1; id <= M; id++)
    {
        int u, v;
        cin >> u >> v;
        g[u].push_back({v, id});
        g[v].push_back({u, id});
        deg[u]++;
        deg[v]++;
    }

    // 1) toate gradele pare
    for (int i = 1; i <= N; i++)
    {
        if (deg[i] % 2)
        {
            cout << -1;
            return 0;
        }
    }

    // găsim un start care are grad > 0 (altfel graful are 0 muchii)
    int start = 1;
    while (start <= N && deg[start] == 0)
        start++;

    if (M == 0)
    {
        // de obicei nu apare (M>=1), dar safe
        cout << -1;
        return 0;
    }
    if (start > N)
    {
        cout << -1;
        return 0;
    }

    // 2) verificare conexitate pe nodurile cu grad > 0
    vector<char> vis(N + 1, 0);
    stack<int> st;
    st.push(start);
    vis[start] = 1;

    while (!st.empty())
    {
        int v = st.top();
        st.pop();
        for (auto [to, id] : g[v])
        {
            if (!vis[to])
            {
                vis[to] = 1;
                st.push(to);
            }
        }
    }

    for (int i = 1; i <= N; i++)
    {
        if (deg[i] > 0 && !vis[i])
        {
            cout << -1;
            return 0;
        }
    }

    // 3) Hierholzer iterativ
    vector<char> used(M + 1, 0);
    vector<int> it(N + 1, 0);
    vector<int> circuit;
    vector<int> stk;

    stk.push_back(start);

    while (!stk.empty())
    {
        int v = stk.back();

        // sărim peste muchiile deja folosite
        while (it[v] < (int)g[v].size() && used[g[v][it[v]].second])
        {
            it[v]++;
        }

        if (it[v] == (int)g[v].size())
        {
            // nu mai avem pe unde ieși => fixăm v în circuit
            circuit.push_back(v);
            stk.pop_back();
        }
        else
        {
            auto [to, id] = g[v][it[v]];
            used[id] = 1;
            stk.push_back(to);
        }
    }

    // circuit ar trebui să aibă M+1 noduri (ciclu)
    if ((int)circuit.size() != M + 1)
    {
        cout << -1;
        return 0;
    }

    // output: M numere x1..xM astfel încât (x1,x2)...(xM,x1) sunt muchii
    // circuit e invers (din cauza modului de construire)
    reverse(circuit.begin(), circuit.end());

    // scriem primele M noduri
    for (int i = 0; i < M; i++)
    {
        cout << circuit[i] << (i + 1 == M ? '\n' : ' ');
    }

    return 0;
}