Cod sursa(job #2970791)

Utilizator popashtefan10Popa Stefan popashtefan10 Data 25 ianuarie 2023 21:47:00
Problema Ciclu Eulerian Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 2.32 kb
#include <iostream>
#include <fstream>
#include <vector>

using namespace std;

const int NMAX = 100000;
const int MMAX = 500000;

class EulerianGraph {
  struct Edge {
    int nod1, nod2;

    Edge(int _nod1 = 0, int _nod2 = 0) : nod1(_nod1), nod2(_nod2) {}

    int other(int nod) {
      return nod1 + nod2 - nod;
    }
  };

  int n;
  vector<int> deg; // deg[i] = gradul nodului i
  vector<bool> visited; // visited[i] = daca muchia i a fost vizitata
  vector<Edge> edges;
  vector<vector<int>> graph; // graph[i] = lista indicilor muchiilor adiacente cu nodul i

public:
  // n = numarul de noduri din graf, nodurile vor fi numerotate de la 1
  void init(int n) {
    this->n = n;
    deg.resize(n + 1);
    graph.resize(n + 1);
  }

  // adauga Edge neorientata
  void addEdge(int from, int to) {
    edges.push_back(Edge(from, to));
    int mIdx = edges.size() - 1;
    graph[from].push_back(mIdx);
    graph[to].push_back(mIdx);
    deg[from]++;
    deg[to]++;
  }

  bool isEulerian() {
    for(int i = 1; i <= n; i++)
      if(deg[i] % 2 == 1)
        return false;
    return true;
  }

  vector<int> getEulerianCycle() {
    vector<int> cycle;
    vector<int> stk;

    visited.resize(edges.size());
    stk.push_back(1);
    while(!stk.empty()) {
      int node = stk.back();
      while(!graph[node].empty() && visited[graph[node].back()])
        graph[node].pop_back();

      if(graph[node].empty()) {
        cycle.push_back(node);
        stk.pop_back();
      }
      else {
        int mIdx = graph[node].back();
        int ngh = edges[mIdx].other(node);
        stk.push_back(ngh);
        visited[mIdx] = true;
      }
    }

    return cycle;
  }
};

int n, m;
vector<pair<int, int>> edges;

void read() {
  ifstream fin("ciclueuler.in");

  fin >> n >> m;
  for(int i = 1; i <= m; i++) {
    int x, y;
    fin >> x >> y;
    edges.push_back({x, y});
  }
}

int main() {
  ofstream fout("ciclueuler.out");

  read();

  EulerianGraph graph;
  graph.init(n);
  for(pair<int, int> edge: edges)
    graph.addEdge(edge.first, edge.second);

  if(graph.isEulerian()) {
    vector<int> cycle = graph.getEulerianCycle();
    cycle.pop_back();
    for(int node: cycle)
      fout << node << ' ';
  }
  else
    fout << "-1";

  return 0;
}