Cod sursa(job #608047)

Utilizator vlad.maneaVlad Manea vlad.manea Data 14 august 2011 18:08:33
Problema Ciclu Eulerian Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 1.62 kb
#include <cstdio>

#include <stack>
#include <queue>
#include <bitset>
#include <vector>

#define INFILE "ciclueuler.in"
#define OUTFILE "ciclueuler.out"
#define NMax 100001
using namespace std;

int N, M;
vector<int> E[NMax];

void read()
{
	int x, y;
	freopen(INFILE, "r", stdin);
	scanf("%d%d", &N, &M);

	// citesc muchiile
	while (M--)
	{
		scanf("%d%d", &x, &y);

		E[x].push_back(y);
		E[y].push_back(x);
	}
}

inline bool hasEvenDegrees()
{
	for (int x = 1; x <= N; ++x)
		if (E[x].size() & 1)
			return false;

	return true;
}

inline bool isConnected()
{
	queue<int> Q;
	bitset<NMax> V;
	int x, y, c;
	vector<int>::iterator i;

	for (Q.push(c = 1), V.set(1); !Q.empty() && c < N; Q.pop())
		for (i = E[x = Q.front()].begin(); i != E[x].end(); ++i)
			if (!V[y = *i])
			{
				V.set(y);
				++c;
				Q.push(y);
			}

	return N == c;
}

inline bool isEulerian()
{
	return hasEvenDegrees() /* && isConnected() */;
}

void write()
{
	freopen(OUTFILE, "w", stdout);
	vector<int>::iterator f;
	stack<int> S;
	int i, x, y;
	
	if (!isEulerian())
	{
		printf("-1\n");
		return;
	}

	// adaug primul nod
	S.push(1);

	// simulez recursia
	while (!S.empty())
	{
		// preiau nodul curent
		x = S.top();

		// are fii?
		if (E[x].size() > 0)
		{
			y = E[x].back();

			// adaug fiul lui
			S.push(y);

			// distrug legatura dinspre x
			E[x].pop_back();

			// distrug legatura dinspre y
			for (f = E[y].begin(); f != E[y].end(); ++f)
				if (*f == x)
				{
					E[y].erase(f);
					break;
				}
		}
		else
		{
			// scot din stiva
			S.pop();

			// scriu nodul
			if (!S.empty())
				printf("%d ", x);
		}
	}
}

int main()
{
	read();
	write();
	return 0;
}