Cod sursa(job #881914)

Utilizator cristina_hoameaCristina cristina_hoamea Data 18 februarie 2013 19:09:24
Problema Ciclu Eulerian Scor 0
Compilator cpp Status done
Runda Arhiva educationala Marime 2.58 kb
#include<fstream>
#include <vector>
#define NMAX 100005

using namespace std;

ifstream fin ("eulerian.in");
ofstream fout ("eulerian.out");

struct nod
{
	int vf;
	struct nod *urm;
};
typedef struct nod * Lista;
Lista C1, C2, sfC1, sfC2;

void citire();
void dfs(int x);
bool conex();
int gradepare();
void determina_ciclu();
int ciclu(int x, Lista& C, Lista& sfC);
void afisare();

vector<int>G[NMAX];
bool viz[NMAX];
int d[NMAX];
int n ,m;

int main()
{
	citire();
	if(conex() && gradepare())
	{
		//fout<<"Graf eulerian"<<'\n';
		determina_ciclu();
		afisare();
	}
	else
		fout<<"-1"<<'\n';
	fout.close();
	return 0;
}

bool conex()
{
	int i;
	//caut un varf neizolat
	for(i=1;i<=n && !d[i];i++);
		if(i>n) return 1;
	//i este varf neizolat
	dfs(i);
	for(i=1;i<=n;i++)
		if(!viz[i] && d[i]) return 0;
	return 1;
}

void dfs(int x)
{
	int i;
	viz[x]=true;
	for(i=0;i<G[x].size();i++)
		if(viz[G[x][i]]==0)
			dfs(G[x][i]);
}

int gradepare()
{
	int i;
	for(i=1;i<=n;i++)
		if(d[i]%2) return 0;
	return 1;
}

void citire()
{
	int x, y, i;
	fin>>n>>m;
	for(i=1;i<=m;i++)
	{//liste de adiacenta
		fin>>x>>y;
		d[x]++; d[y]++;
		G[x].push_back(y);
		G[y].push_back(x);
	}
}

void determina_ciclu()
{
	int x, nr2, total;
	Lista p, q;
	//caut un varf cu gradul nenul
	for(x=1;x<=n && !d[x];x++);
	//x are gradul nenul
	total=ciclu(x, C1, sfC1);
	while(total<m)
	{
		//caut pe C1 un varf cu gradul nenul
		for(p=C1; !d[p->vf]; p=p->urm);
		//acum p indica un varf cu grad nenul
		nr2=ciclu(p->vf, C2, sfC2);
		//reunesc ciclu C1 cu ciclul C2
		q=p->urm; p->urm=C2->urm; sfC2->urm=q;
		total+=nr2;
	}
}

int ciclu(int x, Lista& C, Lista& sfC)
{
	Lista p;
	int y, lg=0, i, j, uvf;//ultimul vf din lista
	//incep ciclu cu vf x
	//aloc memorie pt un nod
	p=new nod;
	p->vf=x; p->urm=NULL;
	C=sfC=p;// el este primul, ultimul, singurul nod din lista
	do
	{
		//caut y, un vf adiacent cu ultimul varf din lista
		uvf=sfC->vf;
		//parcurg linia uvf pana dau un y adiacent cu el
		for(i=0; i<G[uvf].size();i++)
			if( G[uvf][i]!=0)
				break;
		y=G[uvf][i];
		//adaug muchia [uvf,y] in ciclu eulerian
		//aloc memorie
		p=new nod;
		p->vf=y; p->urm=NULL;
		//il adaug la sfarsitul ciclului
		sfC->urm=p; sfC=p;
		lg++;
		//am folosit aceasta muchie, o elimin din graf
		G[uvf][i]=0;
		for(j=0;j<G[y].size();j++)
			if(G[y][j]==uvf)
			{
				G[y][j]=0; break;
			}
		d[uvf]--; d[y]--;
	}
	while(y!=x);
	return lg;
}

void afisare()
{
	Lista p;
	for(p=C1; p;p=p->urm)
		fout<<p->vf<<' ';
	fout<<'\n';
}