Cod sursa(job #610233)

Utilizator claudiumihailClaudiu Mihail claudiumihail Data 25 august 2011 22:47:59
Problema Ciclu Eulerian Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 4.23 kb
#include <fstream>
#include <iostream>
#include <vector>
#include <stack>
#include <list>
#include <string.h>

#define MAXN 100001

using namespace std;

typedef unsigned int uint32;

struct Edge
{
	Edge()
	{}

	Edge(const int s,
		 const int d) : src(s), dest(d)
	{}

	int src, dest;
	list<list<Edge>::iterator>::iterator node1, node2;
};

list<Edge> Edges;
typedef vector< list<list<Edge>::iterator> >  Graph;

int EulerCycle(Graph& graph,
				list<Edge>& Edges,
				list<int>& finalCycle)
{
	int nextVert = 0;
	list<int>::iterator finIt, finItNext;
	
	finIt = finalCycle.begin();
	finItNext = finalCycle.end();
	
	while (nextVert != -1 && !Edges.empty())
	{
		int start;
		int node;
		list<int> currentCycle;
		
		start = nextVert;
		node = start;
		
		currentCycle.push_back(start);
		//cout << "Start = " << start+1 << "\n";
		
		do
		{
			list<list<Edge>::iterator>::iterator it=graph[node].begin();
			
			//cout << "Processing node: " << (*it)->src+1 << "\n";
			//cout << "Processing edge: " << (*it)->src+1 << " " << (*it)->dest+1 << "\n" << "\n";
			
			graph[(*it)->src].erase((*it)->node1);
			if ((*it)->src != (*it)->dest)
			{
				graph[(*it)->dest].erase((*it)->node2);
			}

			if (node == (*it)->src)
				node = (*it)->dest;
			else
				node = (*it)->src;

			Edges.erase((*it));
			
			if (node != start)
				currentCycle.push_back(node);
			else
				break;
		} while(!Edges.empty());
		
		if (!finalCycle.empty())
		{
			if (*finIt == *currentCycle.begin())
				finalCycle.splice(finIt, currentCycle, currentCycle.begin(), currentCycle.end());
			else
				finalCycle.splice(finItNext, currentCycle, currentCycle.begin(), currentCycle.end());
		}
		else
		{
			finalCycle.splice(finIt, currentCycle, currentCycle.begin(), currentCycle.end());
		}
		
		nextVert = -1;
		for (list<int>::iterator it=finalCycle.begin(); it!=finalCycle.end(); ++it)
		{
			list<int>::iterator auxIt = it;
			auxIt++;

			if (!graph[*it].empty())
			{
				finIt = it;
				finItNext = auxIt;

				nextVert = *it;
			}
		}
	}
	
	return 0;
}

int main()
{
	int n,m;
	char *degree;
	Graph graph;
	list<int> path;
	fstream fin("ciclueuler.in", fstream::in);
	fstream fout("ciclueuler.out", fstream::out);
	
	fin >> n >> m;
	//cout << n << " " << m << "\n";
	
	degree = new char[n+1];
	memset(degree, 0, (n+1)*sizeof(char));
	graph.resize(n);
	
	for (int i=0; i<m; ++i)
	{
		int x,y;
		
		fin >> x >> y;
		Edges.push_front(Edge(x-1,y-1));
		
		graph[x-1].push_front(Edges.begin());
		Edges.begin()->node1 = graph[x-1].begin();
		if (x != y)
		{
			graph[y-1].push_front(Edges.begin());
			Edges.begin()->node2 = graph[y-1].begin();
		}
		
		degree[x-1]++;
		degree[x-1] %= 2;
		degree[y-1]++;
		degree[y-1] %= 2;
	}
	
	//cout << "Done 1\n";
	//getchar();
	
	for (int i=0; i<n; ++i)
	{
		if (degree[i]%2)
		{
			//cout << i+1 << " has degree " << degree[i] << "\n";
			fout << -1 << "\n";
			delete[] degree;
			return 0;
		}
	}
	
	delete[] degree;
	
	/*for (list<Edge>::iterator it=Edges.begin(); it!=Edges.end(); ++it)
	{
		cout << "(" << it->src+1 << "," << it->dest+1 << ") ";
	}
	cout << "\n";*/
	
	EulerCycle(graph, Edges, path);
	
	if (Edges.empty())
	{
		for (list<int>::iterator it=path.begin(); it!=path.end(); ++it)
			fout << *it+1 << " ";
		fout << "\n";
		//cout << "Done\n";
		//getchar();
	}
	else
	{
		//cout << "Graph isn't connex so fail\n";
		fout << -1 << "\n";
	}
	
	/*for (int i=0; i<n; ++i)
	{
		cout << i+1 << ": ";
		for (list<list<Edge>::iterator>::iterator it=graph[i].begin(); it!=graph[i].end(); ++it)
		{
			cout << "(" << (*it)->src+1 << " " << (*it)->dest+1 << ") ";
		}
		cout << "\n";
	}
	
	{
		list<Edge>::iterator it=Edges.begin();
		for (int i=0; i<3; ++i)
			it++;
		graph[it->src].erase(it->node1);
		if (it->src != it->dest)
			graph[it->dest].erase(it->node2);
		Edges.erase(it);
	}
	
	cout << "\n";
	for (int i=0; i<n; ++i)
	{
		cout << i+1 << ": ";
		for (list<list<Edge>::iterator>::iterator it=graph[i].begin(); it!=graph[i].end(); ++it)
		{
			cout << "(" << (*it)->src+1 << " " << (*it)->dest+1 << ") ";
		}
		cout << "\n";
	}*/
	
	fin.close();
	fout.close();
	return 0;
}