Cod sursa(job #1836922)

Utilizator BeilandArnoldArnold Beiland BeilandArnold Data 28 decembrie 2016 20:38:11
Problema Ciclu Eulerian Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 1.72 kb

#include <fstream>
#include <vector>
#include <queue>
#include <stack>
#include <list>
#include <algorithm>
using std::vector;
using std::list;

inline bool eulerian(unsigned n, const vector< list<unsigned> > &Adj){
    //bfs
    std::queue<unsigned> bfsq;
    vector<bool> visited(n+1,false);
    bfsq.push(1); visited[1]=true;

    while(!bfsq.empty()){
        unsigned v=bfsq.front(); bfsq.pop();
        for(auto it=Adj[v].begin();it!=Adj[v].end();++it)
            if(!visited[*it]){
                bfsq.push(*it); visited[*it]=true;
            }
    }
    for(unsigned i=1;i<=n;++i) if(!visited[i]) return false; //not a connected graph

    //testing if degrees are even
    for(unsigned i=1;i<=n;++i) if( Adj[i].size() & 1 ) return false;
    return true;
}

int main(){
    std::ifstream fin("ciclueuler.in");
    std::ofstream fout("ciclueuler.out");

    unsigned n,m;
    fin>>n>>m;

    vector< list<unsigned> > Adj(n+1); //used form Adj[1] to Adj[n]

    for(unsigned i=0;i<m;++i){ //read the edges
        unsigned a,b;
        fin>>a>>b;
        Adj[a].push_back(b);
        Adj[b].push_back(a);
    }

    if(!eulerian(n,Adj)) fout<<"-1\n";
    else{
        std::list<unsigned> ciclueul;
        std::stack<unsigned> S;
        unsigned v=1;

        do{
            while(!Adj[v].empty()){
                unsigned w=*Adj[v].begin();
                S.push(v);

                Adj[w].erase(std::find(Adj[w].begin(),Adj[w].end(),v)); //erase edge v <-> w;
                Adj[v].erase(Adj[v].begin());

                v=w;
            }
            v=S.top();
            ciclueul.push_front(v); S.pop();

        } while(!S.empty());

        for(auto i=ciclueul.begin();i!=ciclueul.end();++i) fout<<*i<<' ';
        fout<<'\n';
    }
}