Cod sursa(job #2122374)

Utilizator retrogradLucian Bicsi retrograd Data 4 februarie 2018 23:02:49
Problema Ciclu Eulerian Scor 50
Compilator cpp Status done
Runda Arhiva educationala Marime 1.56 kb
#include <bits/stdc++.h>

using namespace std;

struct EulerWalk {
  int n;
  vector<multiset<int>> G;
  vector<int> deg;
  
  EulerWalk(int n) : n(n), G(n + 1), deg(n + 1, 0) {}
  
  void AddEdge(int a, int b) {
    G[b].insert(a);
    deg[a] += 1; deg[b] -= 1;
    G[a].insert(b);
  }
  
  vector<int> walk;
  void dfs(int node) {
    while (G[node].size()) {
      auto vec = *G[node].begin();
      G[node].erase(G[node].begin());
      G[vec].erase(G[vec].find(node));
      dfs(vec);
    }
    walk.push_back(node);
  }
  
  template<typename Callback>
  void Solve(Callback cb) {
    for (int i = 1; i <= n; ++i) {
      if (deg[i] % 2) 
          AddEdge(i, n);
    }
    // Paths
    vector<int> buff; dfs(n);
    for (auto node : walk) {
      if (node < n) buff.push_back(node);
      else if (buff.size()) {
        cb(buff); buff.clear();
      }
    }
    // Cycles
    for (int i = 0; i < n; ++i) {
      walk.clear(); dfs(i);
      if (walk.size() > 1) cb(walk);
    }
  }
};

int main() {
    ifstream cin("ciclueuler.in");
    ofstream cout("ciclueuler.out");

    int n, m; cin >> n >> m;
    EulerWalk euler(n);
    for (int i = 0; i < m; ++i) {
        int a, b; cin >> a >> b;
        euler.AddEdge(a - 1, b - 1);
    }
    try {
        vector<int> sol;
        euler.Solve([&](vector<int> path) {
            if (path.front() != path.back() or sol.size()) 
                throw 5;
            sol = path; sol.pop_back();
        });
        for (auto x : sol) 
            cout << x + 1 << " "; 
        cout << endl;
    } catch (int) { cout << -1 << endl; }

    return 0;
}