Cod sursa(job #2757788)

Utilizator cristi_macoveiMacovei Cristian cristi_macovei Data 6 iunie 2021 15:23:08
Problema Ciclu Eulerian Scor 30
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 1.97 kb
#include <iostream>
#include <fstream>
#include <vector>
#include <queue>

const int NMAX = 1e5;

class Edge {
public:
  int node;
  int reverse_ref;

  Edge(int node = 0, int reverse_ref = 0):
    node(node), reverse_ref(reverse_ref) {};
};

int n, m;
std::vector<Edge> graph[1 + NMAX];

std::queue<int> q;
bool vis[1 + NMAX];

std::vector<int> stack;
std::vector<int> ans;

void bfs(int src) {
  q.push(src);
  vis[src] = true;

  while (!q.empty()) {
    auto node = q.front();
    q.pop();

    for (auto& edge: graph[node]) {
      if (!vis[edge.node]) {
        q.push(edge.node);
        vis[edge.node] = true;
      }
    }
  }
}

bool has_euler_cycle() {
  for (int i = 1; i <= n; ++i) {
    if (graph[i].size() % 2 != 0)
      return false;
  }

  bfs(1);

  for (int i = 1; i <= n; ++i) {
    if (!vis[i])
      return false;
  }

  return true;
}

inline void del(int node) {
  auto edge = graph[node].back();
  int nb = edge.node;

  std::swap(graph[nb][edge.reverse_ref], graph[nb].back());

  auto other = graph[nb][edge.reverse_ref];
  graph[other.node][other.reverse_ref].reverse_ref = edge.reverse_ref;

  graph[nb].pop_back();

  graph[node].pop_back();
}

void dfs() {
  int node = stack.back();

  while (!graph[node].empty()) {
    auto edge = graph[node].back();

    del(node);

    node = edge.node;

    stack.push_back(node);
  }
}

void solve() {
  stack.push_back(1);

  dfs();

  while (!stack.empty()) {
    if (graph[stack.back()].empty()) {
      ans.push_back(stack.back());

      stack.pop_back();
    }
    else
      dfs();
  }
}

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

  in >> n >> m;

  for (int i = 1; i <= m; ++i) {
    int x, y;
    in >> x >> y;

    graph[x].emplace_back(y, graph[y].size());
    graph[y].emplace_back(x, graph[x].size() - 1);
  }

  if (!has_euler_cycle()) {
    out << "-1\n";
    return 0;
  }

  ans.reserve(1 + m);
  solve();

  ans.pop_back();
  for (auto& i: ans)
    out << i << ' ';

  return 0;
}