Cod sursa(job #280213)

Utilizator cotofanaCotofana Cristian cotofana Data 13 martie 2009 11:45:37
Problema Ciclu Eulerian Scor 70
Compilator cpp Status done
Runda Arhiva educationala Marime 1.89 kb
#include <stdio.h>
#define dim 100010

struct nod
{
	int nr;
	nod *urm;
};
int n, m, gr[dim], fol[dim], ce[dim*5], k;
nod *p[dim];

void add(nod *&p, int nr)
{
	nod *n1=new nod;
	n1->nr=nr;
	n1->urm=p;
	p=n1;
}

int gr_par()
{
	int i;
	for (i=1; i<=n; i++)
		if (gr[i]%2 || !gr[i]) return 0;
	return 1;
}

void dfs(int x)
{
	nod *cur=p[x];
	fol[x]=1;
	while (cur)
	{
		if (cur->nr!=x && !fol[cur->nr]) dfs(cur->nr);
		cur=cur->urm;
	}
}

int conex()
{
	int i;
	dfs(1);
	for (i=2; i<=n; i++)
		if (!fol[i]) return 0;
	return 1;
}

void stergere(nod *&p, int nr)
{
	nod *q, *q1;
	q=p;
	while (q)
	{
		if (q->nr==nr) break;
		q1=q;
		q=q->urm;
	}
	if (q==p)
	{
		p=p->urm;
		delete q;
	}
	else
	{
		q1->urm=q->urm;
		delete q;
	}
}

void construire()
{
	int i, v, k1, ce1[dim*5], cur;
	k=1;
	ce[1]=1;
	do
	{
		cur=p[ce[k]]->nr;

		stergere(p[ce[k]], cur);
		stergere(p[cur], ce[k]);
		
		gr[ce[k]]--;
		gr[cur]--;

		k++;
		ce[k]=cur;
	} while (ce[k]!=ce[1]);
	while (k<m+1)
	{
		for (i=1; i<=k; i++)
			if (gr[i])
			{
				v=i;
				k1=1;
				ce1[1]=ce[i];
				break;
			}
		do
		{
			cur=p[ce1[k1]]->nr;

			stergere(p[ce1[k1]], cur);
			stergere(p[cur], ce1[k1]);			

			gr[ce1[k1]]--;
			gr[cur]--;

			k1++;
			ce1[k1]=cur;
		} while (ce1[k1]!=ce1[1]);
		for (i=k; i>v; i--)
			ce[i+k1-1]=ce[i];
		for (i=1; i<=k1; i++)
			ce[v+i-1]=ce1[i];
		k+=k1-1;
	}
}

int eulerian()
{
	if (!gr_par()) return 0;
	if (!conex()) return 0;
	construire();
	return 1;
}

int main()
{
	int i, a, b;
	freopen("ciclueuler.in", "r", stdin);
	freopen("ciclueuler.out", "w", stdout);
	scanf("%d %d\n", &n, &m);
	for (i=1; i<=m; i++)
	{
		scanf("%d %d\n", &a, &b);
		add(p[a], b);
		add(p[b], a);
		gr[a]++, gr[b]++;
	}
	if(eulerian())
		for (i=1; i<k; i++) printf("%d ", ce[i]);
	else printf("-1\n");
	return 0;
}