Cod sursa(job #1023099)

Utilizator andra23Laura Draghici andra23 Data 6 noiembrie 2013 13:56:57
Problema Ciclu Eulerian Scor 30
Compilator cpp Status done
Runda Arhiva educationala Marime 2.32 kb
#include <iostream>
#include <fstream>
#include <vector>
#include <stack>

using namespace std;

vector<vector<int>> graph;

void dfs(int node, vector<bool> &visited) {
  visited[node] = true;
  for (int i = 0; i < graph[node].size(); i++) {
    int v = graph[node][i];
    if (!visited[v]) {
      dfs(v, visited);
    }
  }
}

bool isConnected() {
  vector<bool> visited;
  visited.resize(graph.size(), false);
  dfs(1, visited);
  for (int i = 1; i < visited.size(); i++) {
    if (!visited[i]) {
      return false;
    }
  }
  return true;
}

void removeEdge(int x, int y) {
  for (int i = 0; i < graph[x].size(); i++) {
    if (graph[x][i] == y) {
      graph[x][i] = graph[x][graph[x].size()-1];
      graph[x].pop_back();
      break;
    }
  }
}

void computeCycle(vector<int> &cycle) {
  int currentNode = 1;
  stack<int> returnNode;
  stack<int> revCycle;
  revCycle.push(currentNode);

  while (true) {
    while (!returnNode.empty() && graph[currentNode].size() == 0) {
      currentNode = returnNode.top();
      returnNode.pop();
      while (revCycle.top() != currentNode) {
        cycle.push_back(revCycle.top());
        revCycle.pop();
      }
      cycle.push_back(currentNode);
      revCycle.pop();
    }
    if (graph[currentNode].size() == 0) {
      break;
    } else {
      int nextNode = graph[currentNode][graph[currentNode].size()-1];
      revCycle.push(nextNode);
      graph[currentNode].pop_back();
      removeEdge(nextNode, currentNode);
      if (graph[currentNode].size() > 0) {
        returnNode.push(currentNode);
      }
      currentNode = nextNode;
    }
  }
  while (!revCycle.empty()) {
    cycle.push_back(revCycle.top());
    revCycle.pop();
  }
}


int main() {
  ifstream f("ciclueuler.in");
  ofstream g("ciclueuler.out");
  int n, m, x, y;
  f >> n >> m;
  graph.resize(n+1);
  for (int i = 0; i < m; i++) {
    f >> x >> y;
    graph[x].push_back(y);
    graph[y].push_back(x);
  }

  bool isEuler = true;
  for (int i = 1; i <= n; i++) {
    if (graph[i].size() % 2 == 1) {
      isEuler = false;
      break;
    }
  }

  if (isEuler && !isConnected()) {
    isEuler = false;
  }

  if (!isEuler) {
    cout << "-1" << endl;
  } else {
    vector<int> eulerCycle;
    computeCycle(eulerCycle);
    for (int i = 0; i < eulerCycle.size()-1; i++) {
      g << eulerCycle[i] << " ";
    }
    g << endl;
  }

  return 0;
}