Cod sursa(job #2947409)

Utilizator dey44andIoja Andrei-Iosif dey44and Data 26 noiembrie 2022 01:44:16
Problema Ciclu Eulerian Scor 60
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 3.13 kb
#include <bits/stdc++.h>

#define forRange(a, b) for(int32_t it = a; it < b; ++it)

using namespace std;

class Graph {
private:
    int32_t nodes, edges;
    unordered_map < int32_t, int32_t > *vertices;
public:
    Graph(int32_t nodes, int32_t edges) {
        assert(nodes > 0 && edges >= 0);
        this -> nodes = nodes;
        this -> edges = edges;
        this -> vertices = new unordered_map < int32_t, int32_t >[this-> nodes + 1];
    }
    void add_edge(int32_t x, int32_t y) {
        this -> vertices[x][y]++;
        this -> vertices[y][x]++;
    }
    void remove_neighbour_of(int32_t node, int32_t neighbour) {
        if(node != neighbour) {
            if(this->vertices[node][neighbour] > 1) {
                this->vertices[node][neighbour]--;
                this->vertices[neighbour][node]--;
            } else {
                this -> vertices[node].erase(neighbour);
                this -> vertices[neighbour].erase(node);
            }
        } else {
            if(this->vertices[node][neighbour] > 2) {
                this->vertices[node][neighbour]--;
                this->vertices[neighbour][node]--;
            } else {
                this -> vertices[node].erase(neighbour);
                this -> vertices[neighbour].erase(node);
            }
        }

    }
    int32_t get_neighbour(int32_t node) const {
        if(!this -> vertices[node].empty())
            return this->vertices[node].begin()->first;
        return -1;
    }
    int32_t get_edges_number() const {
        return this->edges;
    }
};

class GraphManager {
public:
    static Graph read_graph(const string &fileName) {
        ifstream in(fileName);

        int32_t nodes, edges;
        in >> nodes >> edges;
        Graph graph(nodes, edges);
        forRange(0, edges) {
            int32_t node1, node2;
            in >> node1 >> node2;
            graph.add_edge(node1, node2);
        }
        in.close();

        return graph;
    }

    static vector < int32_t > generate_euler_cycle(Graph graph) {
        vector < int32_t > cycle;

        stack < int32_t > stack_nodes;
        stack_nodes.push(1);

        while(!stack_nodes.empty()) {
            int32_t node = stack_nodes.top();

            if(graph.get_neighbour(node) != -1) {
                int32_t neighbour = graph.get_neighbour(node);
                graph.remove_neighbour_of(node, neighbour);
                stack_nodes.push(neighbour);
            } else {
                stack_nodes.pop();
                cycle.push_back(node);
            }
        }
        cycle.pop_back();

        return cycle;
    }
};

class PrintManager {
public:
    static void printVector(const vector < int32_t > &array, int32_t M, const string &fileName) {
        ofstream out(fileName);

        if(array.size() != M) {
            out << -1;
        } else
            for(auto v : array) {
                out << v << " ";
            }

        out.close();
    }
};

int main() {
    Graph graph = GraphManager::read_graph("ciclueuler.in");

    vector < int32_t > cycle = GraphManager::generate_euler_cycle(graph);

    PrintManager::printVector(cycle, graph.get_edges_number(), "ciclueuler.out");

    return 0;
}