Cod sursa(job #1947845)

Utilizator andrei.arnautuAndi Arnautu andrei.arnautu Data 31 martie 2017 14:18:31
Problema Ciclu Eulerian Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 2.4 kb
/**
  *  Worg
  */
#include <stack>
#include <cstdio>
#include <algorithm>

using std::stack;
using std::vector;
FILE *fin = freopen("ciclueuler.in", "r", stdin);
FILE *fout = freopen("ciclueuler.out", "w", stdout);

const int kMaxN = 1 + 100000;
const int kMaxM = 1 + 500000;

/*-------- Structures --------*/
struct Edge {
    int index, v;
    Edge() {}
    Edge(const int _index, const int _v) { index = _index; v = _v; }
};
/*-------- Input data --------*/
int N, M;
vector<Edge > graph[kMaxN];
int crt_index;
/*-------- Eulerian Cycle --------*/
int degree[kMaxN];

bool cycle_exists;
bool checked_edge[kMaxM];

stack<int > my_stack;
vector<int > eulerian_cycle;
/*-------- --------*/

void AddEdge(int u, int v) {
    crt_index ++;
    degree[u] ++;
    degree[v] ++;

    graph[u].push_back(Edge(crt_index, v));
    graph[v].push_back(Edge(crt_index, u));
}

void ReadInput() {
    scanf("%d%d", &N, &M);
    for(int i = 1; i <= M; i++) {
        int u, v; scanf("%d%d", &u, &v);
        AddEdge(u, v);
    }
}

int DeleteNext(int node) {
    while(!graph[node].empty() && checked_edge[graph[node].back().index]) {
        graph[node].pop_back();
    }

    Edge edge = graph[node].back(); graph[node].pop_back();
    checked_edge[edge.index] = true;
    crt_index --; degree[node] --; degree[edge.v] --;

    return edge.v;
}

void EulerianCycle() {
    cycle_exists = true;
    for(int i = 1; i <= N; i++) {
        if(degree[i] % 2 == 1) {
            cycle_exists = false;
        }
    }

    if(cycle_exists) {
        int start = 1;
        while(start <= N && !degree[start]) {
            start ++;
        }
        my_stack.push(start);

        while(!my_stack.empty()) {
            int node = my_stack.top();
            if(degree[node] != 0) {
                my_stack.push(DeleteNext(node));
            } else {
                eulerian_cycle.push_back(node);
                my_stack.pop();
            }
        }

        if(crt_index > 0) {
            cycle_exists = false;
        }
    }
}

void WriteOutput() {
    if(!cycle_exists) {
        printf("-1\n");
    } else {
        for(int i = 0; i < (int)eulerian_cycle.size() - 1; i++) {
            printf("%d ", eulerian_cycle[i]);
        }
        printf("\n");
    }
}

int main() {
    ReadInput();
    EulerianCycle();
    WriteOutput();
    return 0;
}