Cod sursa(job #1731597)

Utilizator jurjstyleJurj Andrei jurjstyle Data 19 iulie 2016 12:59:33
Problema Ciclu Eulerian Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 2.33 kb
#include <fstream>
#include <vector>
#include <list>
#include <stack>

using namespace std ;

ifstream f ("ciclueuler.in") ;
ofstream g ("ciclueuler.out") ;

int N , M ;
vector <int> viz , deg ;
list <int> G[100005] , L ;
stack <int> S ;

void dfs ( int nod_curent )
{
 viz[nod_curent] = 1 ;
 for ( list <int> :: iterator I = G[nod_curent].begin () ; I != G[nod_curent].end () ; ++I )
        if ( viz[*I] == 0 )
            dfs ( *I ) ;
}

int conex ()
{
 dfs ( 1 ) ;
 for ( int cnt = 1 ; cnt <= N ; ++cnt )
    if ( viz[cnt] == 0 )
        return 0 ;
 return 1 ;
}


int euler ()
{
 if ( conex () == 0 )
    return 0 ;
 for ( int cnt = 1 ; cnt <= N ; ++cnt )
    if ( deg[cnt] % 2 == 1 )
        return 0 ;
 return 1 ;
}

void sterge( int v , int w )
{
    deg[v]-- , deg[w]-- ; //scadem gradele cu 1
    G[v].pop_front() ; //taiem muchia (v,w)
    for ( list <int> :: iterator it = G[w].begin() ; it != G[w].end() ; ++it )
        if( *it == v ) //am gasit muchie (w,v)
            {
             G[w].erase( it ) ; //taiem muchia (w,v) si ne oprim
             break ;
            }
}

void euler( int v )
{
 while( true )
    {
     if( G[v].empty() ) //am terminat de format acel ciclu intermediar
        break ;
     int w = G[v].front() ; //luam primul vecin al lui v
     S.push( v ) ; //adaugam v in stiva ca parcurs
     sterge( v, w ) ; //stergem muchia (v,w)
     v = w ; //trecem la nodul w
    }
}

void cauta_ciclu_eulerian()
{
 int nod = 1 ; //pornim din 1
 L.push_back ( nod ) ; //il adaugam la lista cu ciclul
 do  {
      euler( nod ) ; //construim ciclul din nod
      nod = S.top() ; S.pop() ; //ne intoarcem pe stiva si construim un ciclu intermediar pt nod
      L.push_back( nod ) ; //adaugam pe nod la lista noastra
     } while ( !S.empty() ) ; //facem acestea cat timp stiva nu e vida ( initial construim primul ciclu inainte sa avem stiva )
 for ( list <int> :: iterator I = L.begin() ; I != L.end() ; ++I )
    g << *I << " " ;
}

int main ()
{
 f >> N >> M ;
 viz.resize ( N + 1 ) , deg.resize ( N + 1 ) ;
 for ( int cnt = 1 ; cnt <= M ; ++cnt )
    {
     int x , y ;
     f >> x >> y ;
     G[x].push_back ( y ) ;
     G[y].push_back ( x ) ;
     ++deg[x] , ++deg[y] ;
    }
 if ( euler () == 0 )
    g << "-1" ;
 else
    cauta_ciclu_eulerian () ;
}