Cod sursa(job #495695)

Utilizator iconiKMircea Chirea iconiK Data 26 octombrie 2010 15:59:38
Problema Ciclu Eulerian Scor 80
Compilator cpp Status done
Runda Arhiva educationala Marime 1.65 kb
#include <bitset>
#include <algorithm>
#include <fstream>
#include <vector>

using namespace std;

const int maxN = 100000;
const int maxM = 5 * maxN;

vector<int> a[maxN + 1];
bitset<maxN> viz(0);

int gr[maxN + 1];
int c[maxN + 1];
int ce[maxM + 1];

int ciclu(int x);
void df(int k);

void ciclueuler()
{
	ifstream in("ciclueuler.in");
	ofstream out("ciclueuler.out");
	
	int N, M;
	in >> N >> M;

	for (int i = 1; i <= M; i++)
	{
		int x, y;
		in >> x >> y;
		
		a[x].push_back(y);
		a[y].push_back(x);
		
		gr[x]++;
		gr[y]++;
	}
	
	df(1);
	
	for (int i = 1; i <= N; i++)
	{
		if (gr[i] % 2 || (!viz[i] && gr[i]))
		{
			out << -1;
			return;
		}
	}
	
	ce[1] = 1;
	int u = 1;

	for (int p = 1; p <= u;)
	{
		if (gr[ce[p]] > 0)
		{
			int nr = ciclu(ce[p]);
	
			for (int i = u; i >= p + 1; i--)
				ce[i + nr - 1] = ce[i];
	
			for (int i = 2; i <= nr; i++)
				ce[p + i - 1] = c[i];
			
			u += nr - 1;
		}
		else
		{
			p++;
		}
	}
	
	for (int i = 1; i <= u - 1; i++)
		out << ce[i] << ' ';
}

int ciclu(int x)
{
	int nr = 1;
	c[1] = x;
	
	bool ok = true;
	
	do
	{
		for (int i = 0; (size_t) i < a[x].size() && ok; i++)
		{
			int t = a[x][i];

			if (t == c[1])
			{
			    gr[c[1]]--;
				gr[x]--;
				c[++nr] = c[1];

				ok = false;
			}
			else
			{
				c[++nr] = a[x][i];
				
				gr[a[x][i]]--;
				gr[x]--;
			}

			vector<int>::iterator j = find(a[t].begin(), a[t].end(), x);

			a[t].erase(j);
			a[x].erase(a[x].begin());
			
			if (t != c[1])
			{
				x = t;

				break;
			}
		}
	} while (ok);

	return nr;
}

void df(int k)
{
	viz[k] = 1;
	
	for (int i = 0; (size_t) i < a[k].size(); i++)
		if (!viz[a[k][i]])
			df(a[k][i]);
}

int main()
{
	ciclueuler();
}