Cod sursa(job #359617)

Utilizator Ionescu_MariaIonescu Maria-Dorina Ionescu_Maria Data 27 octombrie 2009 21:16:57
Problema Ciclu Eulerian Scor 0
Compilator cpp Status done
Runda Arhiva educationala Marime 2.22 kb
#include<fstream.h>
/* Problema cere defapt sa verificam daca un graf este eulerian
si sa gasim un ciclu eulerian.
Un graf este eulerian daca se pot parcurge toate muchiile fara
a trece de doua ori pe aceeasi muchie.
Un graf este eulerian daca este conex si are gradul tuturor nodurilor par. */
int a[52][52],n,v[102],gr[102],c1[102],dc1,c2[102],dc2,m;
void cit()
{
	int aux,x,y;
	ifstream fin("ciclueuler.in");
	fin>>n>>m;
	aux=m;
	while(aux--)
	{
		fin>>x>>y;
		a[x][y]=1;
		a[y][x]=1;
	}
	fin.close();
}
int conex()
{
	//Functia verifica daca graful este conex
	//Vom parcurge graful in latime si daca am vizitat toate nodurile, graful este conex
	int p,u,k,i;
	p=1; u=1; c1[u]=1; v[1]=1;
	while(p<=u)
	{
		k=c1[p];
		for(i=1;i<=n;i++)
			if(a[k][i]==1&&v[i]==0)
			{
				u++; c1[u]=i; v[i]=1;
			}
		p++;
	}
	for(i=1;i<=n;i++)
		if(v[i]==0)
			return 0;
	return 1;
}
int grad_par()
{
	//Returneaza 1 , daca graful are gradele tuturor nodurilor pare, 0 altfel
	int i,j;
	for(i=1;i<=n;i++)
	{
		gr[i]=0;
		for(j=1;j<=n;j++)
			gr[i]+=a[i][j];
		if(gr[i]%2==1)
			return 0;
	}
	return 1;
}
void ciclu(int r,int c[102],int &dc)
{
	//Construieste in vectorul c , cu dimensiunea dc, un ciclu case incepe in r si se termina tot in r
	//Construirea este posibila deoarece fiecare nod are gradul par
	//Pt a nu trece de doua ori pe aceeasi muchie, dupa ce parcurgem o muchie, aceasta este stearsa
	int j;
	c[1]=r; dc=1; 
	do
	{
		for(j=1;j<=n;j++)
			if(a[c[dc]][j]==1)
			{
				a[c[dc]][j]=0;
				a[j][c[dc]]=0;
				gr[c[dc]]--;
				gr[j]--;
				dc++; c[dc]=j;
				break;
			}
	}
	while(c[dc]!=r);
}
int main()
{
	int i,j;
	cit();
	ofstream fout("ciclueuler.out");
	if(conex()&&grad_par())
		{
			ciclu(1,c1,dc1);
			while(dc1<m+1)
			{
			//Cautam in c1 un nod care mai are cel putin o muchie adiacenta
			for(i=1;i<=dc1;i++)
				if(gr[c1[i]]>0)
					{
						ciclu(c1[i],c2,dc2);
						break;
					}
			//Concatenarea celor doua cicluri
			for(j=dc1;j>=i+1;j--)
				c1[j+dc2-1]=c1[j];
			for(j=2;j<=dc2;j++)
				c1[i+j-1]=c2[j];
			dc1=dc1+dc2-1;
			}
			for(i=1;i<=dc1;i++)
				fout<<c1[i]<<" ";
			fout<<'\n';
		}
	else
		fout<<-1<<'\n';
	fout.close();
	return 0;
}