Cod sursa(job #2869742)

Utilizator the_horoHorodniceanu Andrei the_horo Data 11 martie 2022 19:53:37
Problema Ciclu Eulerian Scor 50
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 1.89 kb
#include <array>
#include <bitset>
#include <cassert>
#include <cstdint>
#include <forward_list>
#include <fstream>
#include <utility>
#include <vector>


constexpr size_t MAX_NODES = 100000;
constexpr size_t MAX_EDGES = 500000;



std::bitset<MAX_EDGES> usedEdge;


std::array<std::vector<std::pair<size_t, size_t>>, MAX_NODES> edges;


bool edgesLeft (size_t node) {
    while (!edges[node].empty() && usedEdge[edges[node].back().second])
        edges[node].pop_back();

    if (edges[node].empty())
        return false;
    return true;
}

constexpr size_t NO_MORE_EDGES = -1;
size_t getNextNode (size_t node) {
    if (edgesLeft(node)) {
        const auto [toNode, edgeIndex] = edges[node].back();
        edges[node].pop_back();

        usedEdge[edgeIndex] = true;
        return toNode;
    } else {
        return NO_MORE_EDGES;
    }
}



int main () {
    std::ifstream in("ciclueuler.in");
    std::ofstream out("ciclueuler.out");

    size_t nodeCount, edgeCount;
    in >> nodeCount >> edgeCount;

    for (size_t i = 0; i != edgeCount; ++ i) {
        size_t u, v;
        in >> u >> v;
        -- u, -- v;

        edges[u].emplace_back(v, i);
        edges[v].emplace_back(u, i);
    }

    for (size_t i = 0; i != edgeCount; ++ i) {
        if (edges[i].size() % 2 == 1) {
            out << "-1\n";
            return 0;
        }
    }

    std::forward_list<size_t> result;
    result.emplace_front(0);

    for (auto it = result.begin(); it != result.end();) {
        if (!edgesLeft(*it)) {
            ++ it;
            continue;
        }

        size_t node = *it;
        do {
             result.emplace_after(it, node);

            node = getNextNode(node);
            assert(node != NO_MORE_EDGES);

        } while (node != *it);
    }

    result.pop_front();

    assert(std::distance(result.begin(), result.end()) == edgeCount);

    for (const auto &node: result)
        out << node + 1 << ' ';
}