Cod sursa(job #2257350)

Utilizator cosmin.pascaruPascaru Cosmin cosmin.pascaru Data 9 octombrie 2018 23:12:23
Problema Ciclu Eulerian Scor 0
Compilator cpp Status done
Runda Arhiva educationala Marime 6.55 kb
#include <stdio.h>
#include <iostream>
#include <fstream>
#include <vector>
#include <array>
#include <algorithm>
#include <vector>
#include <stack>
#include <set>
#include <assert.h>
#include <queue>
#include <chrono>
#include <memory>
#include <cstring>
#include <list>

using LL = long long;
using ULL = int long long;

const std::string _problemName = "eulerian";

#define USE_FILES

#ifdef USE_FILES

namespace std {
std::ifstream fin(_problemName + ".in");
std::ofstream fout(_problemName + ".out");
}

#define cin fin
#define cout fout
#endif

using SimpleGraphBase = std::vector< std::vector<int> >;
class SimpleGraph : public SimpleGraphBase {

public:

    SimpleGraph(int n) : SimpleGraphBase(n) {}

    void addEdge(int x, int y) {
        base()[x].push_back(y);
        base()[y].push_back(x);
    }

    bool hasEulerianCycle() {
        for (const auto& nodeNeighbours : base()) {
            if (nodeNeighbours.size() % 2 != 0) {
                return false;
            }
        }
        return true;
    }

    bool exists(int edge) {
        return edge != -1;
    }

    void dfs(int node) {
        for (auto& edge : base()[node]) {
            if (exists(edge)) {
                int neighbour = edge;

                edge = -1;
                auto it = std::find(base()[neighbour].begin(), base()[neighbour].end(), node);
                *it = -1;

                dfs(neighbour);

                (*eulerianCycle).push_back(node);
            }
        }
    }

    void buildEulerianCycle(std::vector<int>& eulerianCycle) {
        this->eulerianCycle = &eulerianCycle;

        dfs(0);
        eulerianCycle.emplace_back(eulerianCycle.front());
    }

private:

    SimpleGraphBase& base() {
        return (*this);
    }

    std::vector<int>* eulerianCycle;

};

using VectorRemoveGraphBase = std::vector< std::vector<int> >;
class VectorRemoveGraph : public VectorRemoveGraphBase {

public:

    VectorRemoveGraph(int n) : VectorRemoveGraphBase(n) {}

    void addEdge(int x, int y) {
        base()[x].push_back(y);
        base()[y].push_back(x);
    }

    bool hasEulerianCycle() {
        for (const auto& nodeNeighbours : base()) {
            if (nodeNeighbours.size() % 2 != 0) {
                return false;
            }
        }
        return true;
    }

    bool exists(int edge) {
        return edge != -1;
    }

    void dfs(int node) {
        for (auto& edge : base()[node]) {
            if (exists(edge)) {
                int neighbour = edge;

                edge = -1;
                auto it = std::find(base()[neighbour].begin(), base()[neighbour].end(), node);
                base()[neighbour].erase(it);

                dfs(neighbour);

                (*eulerianCycle).push_back(node);
            }
        }
    }

    void buildEulerianCycle(std::vector<int>& eulerianCycle) {
        this->eulerianCycle = &eulerianCycle;

        dfs(0);
        eulerianCycle.emplace_back(eulerianCycle.front());
    }

private:

    VectorRemoveGraphBase& base() {
        return (*this);
    }

    std::vector<int>* eulerianCycle;

};

using LinkedListGraphBase = std::vector< std::pair< std::list<int>, int> >;
class LinkedListGraph : public LinkedListGraphBase {

public:

    LinkedListGraph(int n) : LinkedListGraphBase(n) {}

    void addEdge(int x, int y) {
        base()[x].first.push_back(y);
        base()[x].second++;
        base()[y].first.push_back(x);
        base()[y].second++;
    }

    bool hasEulerianCycle() {
        for (const auto& nodeNeighbours : base()) {
            if (nodeNeighbours.second % 2 != 0) {
                return false;
            }
        }
        return true;
    }

    bool exists(int edge) {
        return true;
    }

    void dfs(int node) {
        decltype(base()[node].first.begin()) next;
        for (auto it = base()[node].first.begin(); it != base()[node].first.end(); it = next) {
            int neighbour = *it;

            next = it;
            ++next;
            base()[node].first.erase(it);

            auto it2 = std::find(base()[neighbour].first.begin(), base()[neighbour].first.end(), node);
            base()[neighbour].first.erase(it2);

            dfs(neighbour);

            (*eulerianCycle).push_back(node);
        }
    }

    void buildEulerianCycle(std::vector<int>& eulerianCycle) {
        this->eulerianCycle = &eulerianCycle;

        dfs(0);
        eulerianCycle.emplace_back(eulerianCycle.front());
    }

private:

    LinkedListGraphBase& base() {
        return (*this);
    }

    std::vector<int>* eulerianCycle;

};


//using LinkedListFastGraphBase = std::vector< std::pair< std::list< std::pair<int, >, int> >;
//class LinkedListGraph : public LinkedListGraphBase {
//
//public:
//
//    LinkedListGraph(int n) : LinkedListGraphBase(n) {}
//
//    void addEdge(int x, int y) {
//        base()[x].first.push_back(y);
//        base()[x].second++;
//        base()[y].first.push_back(x);
//        base()[y].second++;
//    }
//
//    bool hasEulerianCycle() {
//        for (const auto& nodeNeighbours : base()) {
//            if (nodeNeighbours.second % 2 != 0) {
//                return false;
//            }
//        }
//        return true;
//    }
//
//    bool exists(int edge) {
//        return true;
//    }
//
//    void dfs(int node) {
//        decltype(base()[node].first.begin()) next;
//        for (auto it = base()[node].first.begin(); it != base()[node].first.end(); it = next) {
//            int neighbour = *it;
//
//            next = it;
//            ++next;
//            base()[node].first.erase(it);
//
//            auto it2 = std::find(base()[neighbour].first.begin(), base()[neighbour].first.end(), node);
//            base()[neighbour].first.erase(it2);
//
//            dfs(neighbour);
//
//            (*eulerianCycle).push_back(node);
//        }
//    }
//
//    void buildEulerianCycle(std::vector<int>& eulerianCycle) {
//        this->eulerianCycle = &eulerianCycle;
//
//        dfs(0);
//        eulerianCycle.emplace_back(eulerianCycle.front());
//    }
//
//private:
//
//    LinkedListGraphBase& base() {
//        return (*this);
//    }
//
//    std::vector<int>* eulerianCycle;
//
//};

int main() {


    int n, m;
    std::cin >> n >> m;

    SimpleGraph graph(n);

    while (m--) {
        int x, y;
        std::cin >> x >> y;
        --x, --y;
        graph.addEdge(x, y);
    }

    if (!graph.hasEulerianCycle()) {
        std::cout << "-1\n";
        return 0;
    }

    std::vector<int> eulerianCycle;
    graph.buildEulerianCycle(eulerianCycle);

    for (const auto node : eulerianCycle) {
        std::cout << node + 1 << ' ';
    }
    std::cout << '\n';

    return 0;
}