Cod sursa(job #3000427)

Utilizator highonrocketfuelOverweight Raccoon highonrocketfuel Data 12 martie 2023 14:04:53
Problema Ciclu Eulerian Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 1.9 kb
#include <algorithm>
#include <fstream>
#include <iostream>
#include <vector>

const int NMAX = 1e5;
const int MMAX = 5e5;

using namespace std;

int n, m;

vector<int> graph[1 + NMAX];

bool is_used[1 + MMAX];
pair<int, int> edge[1 + MMAX];

vector<int> cycle, stack;

int main() {
  ifstream r("ciclueuler.in");
  ofstream w("ciclueuler.out");

  r >> n >> m;

  for (int i = 1; i <= m; ++i) {
    int a, b;
    r >> a >> b;

    graph[a].push_back(i);
    graph[b].push_back(i);

    edge[i] = {a, b};
  }

  for (int i = 1; i <= n; ++i) {
    if (graph[i].size() % 2 == 1) {
      w << -1 << '\n';
      return 0;
    }
  }

  /*
  idea, explained with recursion:

  euler(node) {
    while (node has neighbours) {
      next_node = random neighbour

      remove connection between node and next_node

      call euler(next_node)
    }

    add node to the cycle
  }
  */

  // starting at 1
  stack.push_back(1);

  while (!stack.empty()) {
    int node = stack.back();

    // while node has neighbours, add each one of them to the stack
    if (!graph[node].empty()) {
      int edge_id = graph[node].back();
      graph[node].pop_back();

      if (!is_used[edge_id]) {
        is_used[edge_id] = true;

        /*
        they never explain this kind of shit, so here it is
        the pair will be either {current_node, next_node} or
        {next_node, current_node} doing the thing below will cancel the value of
        next_node since a ^ a is always zero
        */
        int next_node = edge[edge_id].first ^ edge[edge_id].second ^ node;

        stack.push_back(next_node);
      }
    }
    // when it doesn't anymore, add it to the cycle
    else {
      stack.pop_back();
      cycle.push_back(node);
    }
  }

  reverse(cycle.begin(), cycle.end());

  for (int i : cycle) {
    w << i << ' ';
  }
  w << '\n';

  return 0;
}