Cod sursa(job #483257)

Utilizator bent_larsenSturzu Antonio-Gabriel bent_larsen Data 7 septembrie 2010 17:38:20
Problema Ciclu Eulerian Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 2.77 kb
#include<iostream>
#include<vector>
#include<queue>
#include<fstream>
using namespace std;

const int vf=100000;//maximum number of vertices

int grad[vf],n,m;
vector<int> ad[vf];

class Link{
	int val;
	Link* next;
	Link* prev;
public:
	Link(Link *next,Link* prev,int val)
	{
		this->next=next;
		this->prev=prev;
		if(prev!=0)
			prev->next=this;
		this->val=val;
	}
	void splice(Link *cell)
	{
		Link* p1=next;
		Link* p2=cell->prev;
		next=cell;
		cell->prev=next;
		p2->next=p1;
		p1->prev=p2;
	}
	void set(Link*next)
	{
		this->next=next;
	}
	Link* getnext()
	{
		return next;
	}
	int getval()
	{
		return val;
	}
};


int BFS()
{
	queue<int> q;
	int viz[vf],count=0;
	memset(viz,0,sizeof(viz));

	int nod=0;
	viz[nod]=1;
	q.push(nod);
	while(!q.empty())
	{
		nod=q.front();
		q.pop();
		count++;
		for(int i=0;i<(int) ad[nod].size();i++)
		{
			if(viz[ad[nod][i]]==0)
			{
				viz[ad[nod][i]]=1;
				q.push(ad[nod][i]);
			}
		}
	}
	if(count<n)
		return 0;
	return 1;
}

int eulerian()
{
	int rez=1;

	if(BFS()==1)
	{
		for(int i=0;i<vf;i++)
			if(grad[i]&1)
			{
				rez=0;
				break;
			}
	}
	else
		rez=0;
	return rez;
}

void del(int nod,int nod1)
{
	--grad[nod];
	--grad[nod1];
	ad[nod].erase(ad[nod].begin());
	for(int i=0;i<(int) ad[nod1].size();i++)
	{
		if(ad[nod1][i]==nod)
		{
			ad[nod1].erase(ad[nod1].begin()+i);
			break;
		}
	}
}

Link* visit(int nod)
{
	Link *curent=0,*first,*link=0;
	while(grad[nod]>0)
	{
		int nod1=ad[nod][0];
		del(nod,nod1);
		link=new Link(0,curent,nod);
		if(curent==0)
			first=link;
		curent=link;
		nod=nod1;
	}
	if(link)
		link->set(first);
	return link;
}

Link *prim=0;
void euler()
{
	int v=0;
	prim=visit(v);
	prim=prim->getnext();
	Link* u=prim->getnext();

	while(u!=prim)
	{
		int nod=u->getval();
		Link* cell=visit(nod);
		if(cell==0)
			u=u->getnext();
		else //do the splice thing
		{
			Link* save=cell->getnext()->getnext();
			cell->splice(u);
			u=save;
		}
	}
}

void read_input()
{
	ifstream in("ciclueuler.in");

	in>>n>>m;
	int u,v;
	for(int i=0;i<m;i++)
	{	
		in>>u>>v;
		u--;
		v--;
		++grad[u],++grad[v];
		ad[u].push_back(v);
		ad[v].push_back(u);
	}
	in.close();
}

void write()
{
		ofstream out("ciclueuler.out");

		if(eulerian())
		{
			euler();
			out<<prim->getval()+1<<" ";
			Link *p=prim->getnext();
			while(p!=prim)
			{		
				out<<p->getval()+1<<" ";
				p=p->getnext();
			}
		}
		else
			out<<"-1\n";
		out.close();
}

void destroy()
{
	Link *p=prim;

	if(p==0)
		return;
	p=prim->getnext();
	delete prim;
	while(p!=prim)
	{
		Link *next=p->getnext();
		delete p;
		p=next;
	}
}

int main()
{
	read_input();
	write();
	destroy();
}