Cod sursa(job #485399)

Utilizator darkseekerBoaca Cosmin darkseeker Data 18 septembrie 2010 11:48:53
Problema Ciclu Eulerian Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 2.34 kb
#include <cstdio>
#include <cstdlib>
#define NMAX 100010
#define MMAX 500010
int c[MMAX],c1[MMAX],*g[NMAX],grad[NMAX],n,m;
bool viz[MMAX];
FILE *fin=freopen("ciclueuler.in","r",stdin);
FILE *fout=freopen("ciclueuler.out","w",stdout);
void citeste()
{
	int i,e1,e2;
	fscanf(fin,"%d %d",&n,&m);
	for(i=1;i<=n;i++)
	{
		g[i]=(int*)realloc(g[i],sizeof(int));
		g[i][0]=0;
	}
	for(i=1;i<=m;i++)
	{
		fscanf(fin,"%d %d",&e1,&e2);
		g[e1][0]++;
		g[e1]=(int*)realloc(g[e1],(g[e1][0]+1)*sizeof(int));
		g[e1][g[e1][0]]=e2;
		grad[e1]++;
		g[e2][0]++;
		g[e2]=(int*)realloc(g[e2],(g[e2][0]+1)*sizeof(int));
		g[e2][g[e2][0]]=e1;
		grad[e2]++;
	}
}
void dfs(int nod)
{
	int i;
	viz[nod]=1;
	for(i=1;i<=g[nod][0];i++)
		if(!viz[g[nod][i]])
		{
			viz[g[nod][i]]=1;
			dfs(g[nod][i]);
		}
}
bool este_eulerian()
{
	int i;
	dfs(1);
	for(i=1;i<=n;i++)
		if(g[i][0]%2!=0)
			return 0;
	for(i=1;i<=n;i++)
		if(!viz[i])
			return 0;
	return 1;
}
void sterge(int n1,int n2)
{
	int i;
	grad[n1]--;
	grad[n2]--;
	for(i=1;i<=g[n1][0];i++)
		if(g[n1][i]==n2)
			{
				g[n1][i]=0;
				break;
		}
	for(i=1;i<=g[n2][0];i++)
		if(g[n2][i]==n1)
			{
				g[n2][i]=0;
				break;
		}
}
	
void construieste_ciclu_eulerian()
{
	int lc,lc1,sc1,i,gasit;
	if(!este_eulerian())
		fprintf(fout,"%d",-1);
	else
	{
		lc=1;
		c[lc]=1;
		do //creez primul ciclu
		{
			gasit=0;
			for(i=1;i<=g[c[lc]][0]&&!gasit;i++)
			{
				gasit=0;
				if(g[c[lc]][i]!=0)
				{
					gasit=1;
					lc++;//lungimea primului ciclcu
					c[lc]=g[c[lc-1]][i];
					sterge(c[lc-1],c[lc]);
				}
			}
		}while(c[lc]!=c[1]);
		while(lc-1<m)
		{
			for(i=1;i<=lc;i++)
			if(grad[c[i]]!=0)
			{
				lc1=1;
				c1[lc1]=c[i];
				sc1=i;
				break;
			}
		do//creez al 2-lea ciclu
		{
			gasit=0;
			for(i=1;i<=g[c1[lc1]][0]&&!gasit;i++)
			{
				gasit=0;
				if(g[c1[lc1]][i]!=0)
				{
					gasit=1;
					lc1++;
					c1[lc1]=g[c1[lc1-1]][i];
					sterge(c1[lc1-1],c1[lc1]);
				}
			}
		}while(c1[lc1]!=c1[1]);
		for(i=lc;i>=sc1;i--)//deplasez nodurile aflate pana in nodul d start al ciclului 2 cu lc1 pozitii spre dreapta
			c[i+lc1-1]=c[i];
		for(i=1;i<lc1;i++)
			c[sc1+i]=c1[i+1];
		lc+=lc1-1;
		}
		for(i=1;i<=m;i++)
			fprintf(fout,"%d ",c[i]);
	}
}
int main()
{
	citeste();
	construieste_ciclu_eulerian();
	return 0;
}