Cod sursa(job #2341511)

Utilizator petru.ciocirlanPetru Ciocirlan petru.ciocirlan Data 11 februarie 2019 21:28:22
Problema Ciclu Eulerian Scor 0
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 2.82 kb
#include <fstream>
#include <vector>
#include <stack>
#include <bitset>
using namespace std;

#define FILENAME "ciclueuler"
ifstream fin (FILENAME".in");
ofstream fout(FILENAME".out");

const int INF = 0x3f3f3f3f;
const int MAXN = 100000 + 16;
const int MAXM = 500000 + 16;

stack < int > ST;
vector < pair < int, int > > Edge[MAXN];
//vector < pair < int, int > > TreeEdge[MAXN], ReturnEdge[MAXN];
deque < pair < int, int > > FollowUp[MAXN];
int Deg[MAXN];
int N, M, K;

void citire();
bool isValid();
void dfs(int);
void createEuler(int);

int main()
{
    citire();
    if(isValid())
    {
        dfs(1);
        createEuler(1);
    }
    else
        fout << "-1\n";

    return 0;
}

bitset < MAXM > VizM;
void createEuler(int nod)
{
    VizM.reset();

    for(int i = 1; i <= M; ++i)
    {
        fout << nod << ' ';
        while(!FollowUp[nod].empty() && VizM.test(FollowUp[nod].front().second))
            FollowUp[nod].pop_front();

        int next = FollowUp[nod].front().first;
        VizM.set(FollowUp[nod].front().second);
        FollowUp[nod].pop_front();
        nod = next;
    }
}

bool VizN[MAXN];
//int Return[MAXN], Father[MAXN];
void dfs(int rad)
{
    /*
    Return[rad] = INF;
    Father[rad] = 0;
    */

    //int level = 0;
    ST.push(rad);
    while(!ST.empty())
    {
        int nod = ST.top();
        VizN[nod] = true;

        while(!Edge[nod].empty() && VizM.test(Edge[nod].back().second))
            Edge[nod].pop_back();

        if(Edge[nod].empty())
        {
            /*
            if(Return[Father[nod]] > Return[nod])
                Return[Father[nod]] = Return[nod];
            --level;
            */
            ST.pop();
        }
        else
        {
            int next = Edge[nod].back().first;
            VizM.set(Edge[nod].back().second);
            Edge[nod].pop_back();

            ++K;
            if(VizN[next])
            {
                FollowUp[nod].push_front(make_pair(next, K));
                if(nod != next)
                    FollowUp[next].push_front(make_pair(nod, K));
                //Return[nod] = level;
            }
            else
            {
                FollowUp[nod].push_back(make_pair(next, K));
                FollowUp[next].push_back(make_pair(nod, K));
                //++level;
                //Father[next] = nod;
                ST.push(next);
            }
        }
    }
}

bool isValid()
{
    for(int i = 1; i <= N; ++i)
        if(Deg[i]&1)
            return false;

    return true;
}

void citire()
{
    fin >> N >> M;
    for(int i = 1; i <= M; ++i)
    {
        int a, b;
        fin >> a >> b;
        Edge[a].push_back(make_pair(b, i));
        Edge[b].push_back(make_pair(a, i));
        ++Deg[a], ++Deg[b];
    }
}