Cod sursa(job #2343492)

Utilizator enedumitruene dumitru enedumitru Data 14 februarie 2019 01:04:50
Problema Ciclu Eulerian Scor 80
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 2.95 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 MAXN = 100000 + 16;
const int MAXM = 500000 + 16;

vector < pair < int, int > > Edge[MAXN], returnBranch[MAXN];
bitset < MAXM > VizM;
int Deg[MAXN];
int N, M;

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;
}

void createEuler(int nod)
{
    VizM.reset();

    for(int i = 1; i <= M; ++i)
    {
        fout << nod << ' ';

        bool need = true;
        if(!returnBranch[nod].empty())
        {
            need = false;
            while(!returnBranch[nod].empty() && VizM.test(returnBranch[nod].back().second))
                returnBranch[nod].pop_back();

            if(!returnBranch[nod].empty())
            {
                int next = returnBranch[nod].back().first;
                VizM.set(returnBranch[nod].back().second);
                returnBranch[nod].pop_back();
                nod = next;
            }
            else
                need = true;

        }

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

            int next = Edge[nod].back().first;
            VizM.set(Edge[nod].back().second);
            Edge[nod].pop_back();
            nod = next;
        }

    }
}

bitset < MAXN > VizN;
stack < unsigned int > ST, iterate;
void dfs(int rad)
{
    ST.push(rad);
    iterate.push(0);

    while(!ST.empty())
    {
        int nod = ST.top();
        int poz = iterate.top();

        VizN.set(nod);
        while((unsigned)poz < Edge[nod].size() && VizM.test(Edge[nod][poz].second))
            ++poz;

        if((unsigned)poz >= Edge[nod].size())
        {
            ST.pop();
            iterate.pop();
        }
        else
        {
            int next = Edge[nod][poz].first;
            int id = Edge[nod][poz].second;
            VizM.set(id);
            ++poz;
            iterate.top() = poz;

            if(VizN.test(next))
            {
                returnBranch[nod].push_back(make_pair(next, id));
                returnBranch[next].push_back(make_pair(nod, id));
            }
            else
            {
                ST.push(next);
                iterate.push(0);
            }
        }
    }
}

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];
    }
}