Pagini recente » Cod sursa (job #835285) | Cod sursa (job #1437544) | Cod sursa (job #38981) | Cod sursa (job #30502) | Cod sursa (job #1390971)
#include <fstream>
#include <list>
#include <queue>
#include <stack>
using namespace std;
ifstream fin("ciclueuler.in");
ofstream fout("ciclueueler.out");
#define TR( C, it ) \
for( list<int>::iterator it = C.begin(); it != C.end(); it++ )
#define pb push_back
#define NX 100010
list<int> G[NX], P;
stack<int> S;
queue<int> Q;
int N, M, deg[NX], viz[NX];
void readGraph()
{
int u,v;
fin>>N>>M;
while(M--)
{
fin>>u>>v;
G[u].pb(v); deg[u]++; // Add the adiacent vertex to
G[v].pb(u); deg[v]++; // the list of edges and increment degree
}
}
// Check if graph is still connected when we remove a edge
// Marks the viz[i] = 1 for all vertexes conex with 1
void BFS(int v)
{
Q.push(v); viz[v]=1;
while(!Q.empty())
{
v = Q.front(); Q.pop();
TR( G[v], u ) // bullshit parser error
if(!viz[*u])
Q.push(*u), viz[*u]=1;
}
}
bool isConnected()
{
BFS(1);
for(int v=2; v<=N; ++v)
if(viz[v]==0)
return true; // According to the BFS, it wasn't visited
return false;
}
bool isEulerian()
{
if(!isConnected()) // A eulerian graph must be connected
return false;
for(int v=1; v<=N; v++) // The degrees must be even
if(deg[v]%2!=0)
return false;
return true;
}
void eraseEdge(int v, int u)
{
deg[v]--; deg[u]--;
G[v].pop_front(); // erase first edge (aleator)
TR( G[u], it )
if( *it == v)
{
G[u].erase(it);
break;
}
}
void euler(int v)
{
while(!G[v].empty())
{
int u = G[v].front();
S.push(v);
eraseEdge(v, u);
v=u;
}
}
bool fetchResult()
{
if(!isEulerian())
return false;
int v=1;
do
{
euler(v);
v = S.top(); S.pop();
P.pb(v);
}while(!S.empty());
return true;
}
void writeCycle()
{
TR( P, v)
fout<<*v<<" ";
fout<<"\n";
}
int main() {
return 0;
readGraph();
if(fetchResult())
writeCycle();
else
fout<<"-1";
}