Cod sursa(job #689483)
#include <fstream>
#include <vector>
#include <stack>
#include <cstdlib>
using std::vector;
struct edge_type
{
int x,y;
bool valid;
edge_type(int _x,int _y,bool _valid) : x(_x) , y(_y), valid(_valid) {}
};
/*
Check if graph has Euler's property
*/
bool isEuler(vector<vector<int> > &G,vector<edge_type> & edges,int V,int E)
{
{
vector<int> deg(V + 1);
for(int i = 0; i < E; ++i)
deg[edges[i].x] ++, deg[edges[i].y] ++;
for(int i = 1; i <= V; ++i)
if(deg[i] & 1)
return false;
}
{
vector<int> Q(V + 1);
int le = 0, ri = 0;
vector<bool> vis(V + 1,false);
int start = rand() % V + 1;
Q[ri++] = start;
vis[start] = true;
while(le < ri)
{
int q = Q[le++];
for(vector<int>::iterator i = G[q].begin() ; i != G[q].end(); ++i)
if(!vis[edges[*i].x]) //parcurg de la y la x muchia
Q[ri++] = edges[*i].x, vis[edges[*i].x] = true;
else if(!vis[edges[*i].y]) //parcurg de la x la y muchia
Q[ri++] = edges[*i].y, vis[edges[*i].y] = true;
}
for(int i = 1; i <= V; ++i)
if(vis[i] == 0)
return false;
}
return true;
}
/*
Fleury's algorithm
//TO DO
*/
/*
Hierholzer's algorithm
*/
vector<int> EulerTour(vector<vector<int> > &G,vector<edge_type> & edges,int V,int E)
{
vector<int> tour; //contains indices of edges
std::stack<int> vertex;
int start = rand() % V + 1;
vertex.push(start);
while(!vertex.empty())
{
int v = vertex.top();
vector<int>::iterator i = G[v].begin();
if(i != G[v].end())
{
if(edges[*i].x == v)
{
vertex.push(edges[*i].y);
for(vector<int>::iterator j = G[edges[*i].y].begin(); j != G[edges[*i].y].end();)
if(*j == *i)
j = G[edges[*i].y].erase(j);
else ++j;
}
else //edges[*i].y == v
{
vertex.push(edges[*i].x);
for(vector<int>::iterator j = G[edges[*i].x].begin(); j != G[edges[*i].x].end();)
if(*j == *i)
j = G[edges[*i].x].erase(j);
else ++j;
}
G[v].erase(i);
}
else tour.push_back(vertex.top()),vertex.pop();
}
tour.pop_back();
return tour;
}
int main()
{
std::ifstream in("ciclueuler.in");
std::ofstream out("ciclueuler.out");
int V,E;
vector < edge_type > edges;
vector < vector<int> > G;
in >> V >> E;
G.resize(V + 1);
int x,y;
for(int i = 0; i < E; ++i)
{
in >> x >> y;
edges.push_back(edge_type(x,y,true));
G[x].push_back(i);
G[y].push_back(i);
}
if(!isEuler(G,edges,V,E))
{
out << -1;
}
else
{
vector<int> tour( EulerTour(G,edges,V,E) );
for(vector<int>::iterator i = tour.begin(); i != tour.end(); ++i)
{
out << *i << " ";
}
}
return 0;
}