Cod sursa(job #1344495)

Utilizator shervladVlad Seremet shervlad Data 16 februarie 2015 19:25:56
Problema Ciclu Eulerian Scor 0
Compilator cpp Status done
Runda Arhiva educationala Marime 2.55 kb
#include <fstream>
#include <list>
#include <iostream>
#include <algorithm>
#include <memory.h>

using namespace std;

ifstream in("ciclueuler.in");
ofstream out("cuclieuler.out");


class Graph{

public:
	int v;
	list<int> *al;

	Graph(int n){
		v=n;
		al = new list<int>[v+1];
	}
	~Graph(){
		delete[] al;
	}

	void AddEdg(int u,int v);
	void RmvEdg(int u,int v);
	bool IsConnected();
	int IsEuler();
	void EulerPath(int u);
	void dfs(int u,bool visited[]);
	void dfs(int u,bool visited[],int &cnt);
	bool IsProper(int u,int v);

};

void Graph::AddEdg(int u,int v){
	al[u].push_back(v);
	al[v].push_back(u);
}
void Graph::RmvEdg(int u,int v){
	list<int>::iterator it=find(al[u].begin(),al[u].end(),v);
	*it=-1;
	it=find(al[v].begin(),al[v].end(),u);
	*it=-1;
}
void Graph::dfs(int u,bool visited[]){
	visited[u]=true;
	list<int>::iterator it;
	for(it=al[u].begin();it!=al[u].end();it++)
	{
		if(*it!=-1 && !visited[*it]){
			dfs(*it,visited);
		}
	}
}
void Graph::dfs(int u,bool visited[],int &cnt){
	visited[u]=true;
	cnt++;
	list<int>::iterator it;
	for(it=al[u].begin();it!=al[u].end();it++)
	{
		if(*it!=-1 && !visited[*it]){
			dfs(*it,visited,cnt);
		}
	}
}
bool Graph::IsConnected(){
	int i;
	for(i=1;i<=v;i++)
		if(al[i].size()>0)
			break;
	if(i==v)
		return true;

	bool visited[v+1];
	memset(visited,false,v+1);
	dfs(i,visited);
	for(int i=1;i<=v;i++){
		if(al[i].size()>0 && !visited[i])
			return false;
	}
	return true;
}

int Graph::IsEuler(){
	bool cnt=IsConnected();
	if(!cnt) return false;
	int odd=0;
	for(int i=1;i<=v;i++){
		if(al[i].size() & 1)
			odd++;
	}
	if(odd>2)
		return 0;
	if(odd==0)
		return 1;
	if(odd==2)
		return 2;
}

bool Graph::IsProper(int u,int v){
	int cnt=0,cnt2=0;
	list<int>::iterator it;
	for(it=al[u].begin();it!=al[u].end();it++){
		if(*it!=-1)
			cnt++;
	}
	if(cnt==1) return true;

	bool viz1[v+1];
	memset(viz1,false,v+1);
	cnt=0; cnt2=0;
	dfs(u,viz1,cnt);
	RmvEdg(u,v);
    bool viz2[v+1];
	memset(viz2,false,v+2);
	dfs(u,viz2,cnt2);
	AddEdg(u,v);
	if(cnt2<cnt) return false;
	return true;


}
void Graph::EulerPath(int u){
	cout<<u<<" ";
	list<int>::iterator it;
	for(it=al[u].begin();it!=al[u].end();it++){
        int v=*it;
		if(v!=-1 && IsProper(u,v)){
			RmvEdg(u,v);
			EulerPath(v);
		}
	}
}

int main(){

	int n,m;
	in >> n >> m;
	Graph G(n);
	int x,y;
	for(int i=1;i<=m;i++){
		in >> x >> y;
		G.AddEdg(x,y);
	}
	if(G.IsEuler()==1){
		G.EulerPath(1);
	}
	else
		out<<-1<<"\n";
	return 0;
}