Cod sursa(job #1743708)

Utilizator mouse_wirelessMouse Wireless mouse_wireless Data 18 august 2016 16:35:38
Problema Ciclu Eulerian Scor 80
Compilator cpp Status done
Runda Arhiva educationala Marime 2.27 kb
#include <cstdio>
#include <vector>
#include <list>
#include <stack>
#include <cstring>
using namespace std;

class edge {
public:
	int vertex;
	list<edge*>::iterator complement;
	edge(int v, list<edge*>::iterator e) : vertex(v), complement(e) { }
};

vector< list<edge*> > G;
vector<int> deg;
stack<int> S;
vector<char> viz;

#define CLEAR_STACK(s) { \
while (!s.empty()) \
	s.pop(); \
}

void addEdge(int x, int y) {
	edge *e1 = new edge(y, G[y].end());
	G[x].push_front(e1);
	edge *e2 = new edge(x, G[x].begin());
	G[y].push_front(e2);
	e1->complement = G[y].begin();
	++deg[x], ++deg[y];
}

void deleteEdge(int x) {
	edge *e = *(G[x].begin());
	edge *e2 = *(e->complement);
	G[x].pop_front();
	G[e->vertex].erase(e->complement);
	delete e2;
	delete e;
}

char isConnected() {
	CLEAR_STACK(S);
	S.push(0);
	memset(&viz[0], 0, sizeof(viz[0]) * viz.size());
	while (!S.empty()) {
		int t = S.top();
		S.pop();
		if (viz[t]) continue;
		viz[t] = 1;
		for (list<edge*>::iterator i = G[t].begin(), end = G[t].end(); i != end; ++i)
		if (!viz[(*i)->vertex])
			S.push((*i)->vertex);
	}
	for (vector<char>::iterator i = viz.begin(), end = viz.end(); i != end; ++i)
	if (!(*i))
		return 0;
	return 1;
}

char isEuler() {
	if (!isConnected())
		return 0;
	for (vector<int>::iterator i = deg.begin(), end = deg.end(); i != end; ++i)
	if ((*i) & 1)
		return 0;
	return 1;
}

void visitOneCycle(int t) {
	while (true) {
		if (G[t].empty())
			break;
		int dest = (*G[t].front()).vertex;
		deleteEdge(t);
		S.push(t);
		t = dest;
	}
}

void printEulerCycle() {
	CLEAR_STACK(S);
	memset(&viz[0], 0, sizeof(viz[0]) * viz.size());
	int t = 0;
	do {
		visitOneCycle(t);
		t = S.top(); S.pop();
		printf("%d ", t + 1);
	} while (!S.empty());
	putchar('\n');
}

int main() {
#ifdef INFOARENA
	freopen("ciclueuler.in", "r", stdin);
	freopen("ciclueuler.out", "w", stdout);
#endif
	int N, M;
	scanf("%d%d", &N, &M);
	G.resize(N);
	deg.resize(N, 0);
	viz.reserve(M);
	viz.resize(N);
	for (int i = 0; i < M; i++) {
		int x, y;
		scanf("%d%d", &x, &y);
		--x, --y;
		addEdge(x, y);
	}
	if (!isEuler()) {
		printf("%d\n", -1);
		return 0;
	}
	printEulerCycle();
	return 0;
}

/*
TEST CASE:

4 6
1 2
1 3
2 2
2 3
3 4
3 4
*/