Cod sursa(job #1998556)

Utilizator GoogalAbabei Daniel Googal Data 8 iulie 2017 13:21:27
Problema Ciclu Eulerian Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 2.97 kb
#include <iostream>
#include <fstream>
#include <queue>
#include <stack>

using namespace std;

ifstream in("ciclueuler.in");
ofstream out("ciclueuler.out");

const int nmax = 100000;

struct Edge {
  int to;
  int rev; //indicele muchiei opuse in g[to]. g[to][rev] e muchia opusa
  bool del;
};

vector<Edge> g[1 + nmax];
bool mark[1 + nmax];
int start, n, m;
vector<int> sol;

//la aceasta reprezentare trebuie sa fim atenti la muchii din nod in acelasi nod
void addedge(int i, int j) {
  int loop = 0;
  if(i == j)
    loop = 1;

  Edge direct  = {j, g[j].size() + loop, false};
  Edge inverse = {i, g[i].size(), false};
  g[i].push_back(direct);
  g[j].push_back(inverse);
  start = i;
}

void bfs() {
  queue < int > q;
  mark[start] = true;
  q.push(start);
  while(!q.empty()){
    int from = q.front();
    q.pop();
    for(int i = 0; i < g[from].size(); i++){
      Edge &e = g[from][i];
      if(mark[e.to] == false){
        mark[e.to] = true;
        q.push(e.to);
      }
    }
  }
}

void eulercircuitit(int start) {
  stack<int> st;
  st.push(start);

  while(!st.empty()) {
    int from = st.top();
    int k = 0;
    for(int i = 0; i < g[from].size(); i++){
      Edge &e = g[from][i];
      if(e.del == false){
        k++;
        e.del = true;
        g[e.to][e.rev].del = true;
        st.push(e.to);
      }
    }
    if(k==0){
      sol.push_back(from);
      st.pop();
    }
  }
}

void eulercircuit(int from) {
  for(int i = 0; i < g[from].size(); i++){
    Edge &e = g[from][i];
    if(e.del == false){
      e.del = true;
      g[e.to][e.rev].del = true;
      //cout<<from<<" -> "<<e.to<<endl;
      eulercircuit(e.to);
    }
  }
  sol.push_back(from);
}

void eulercircuit2(int from) {
  while(0 < g[from].size()) {
    Edge &e = g[from].back();
    if(e.del == false) {
      int to = e.to;
      g[e.to][e.rev].del = true;
      g[from].pop_back();
      eulercircuit2(to);
    } else
      g[from].pop_back();
  }
  sol.push_back(from);
}

void eulercircuit2i(int from) {
  stack < int > st;
  st.push(from);
  while(!st.empty()){
    int from = st.top();
    if(0 < g[from].size()) {
      Edge e = {g[from].back().to, g[from].back().rev, g[from].back().del};
      g[from].pop_back();
      if(e.del == false) {
        g[e.to][e.rev].del = true;
        st.push(e.to);
      }
    } else {
      sol.push_back(from);
      //cout << from << '\n';
      st.pop();
    }
  }
}


int main() {
  in >> n >> m;
  for(int i = 1; i <= m; i++){
    int x, y;
    in >> x >> y;
    addedge(x, y);
  }
  bfs();

  bool hassol = true;
  for(int i = 1; i <= n; i++){
    if(0 < g[i].size()){
      if(mark[i] == false || g[i].size() % 2 == 1)
        hassol = false;
    }
  }

  if(hassol == true) {
    eulercircuit2i(start);
    //cout << sol.size();
    for(int i = sol.size()-1; 0 < i; i--)
      out << sol[i] << " ";
  } else {
    out << "-1\n";
  }
  return 0;
}