Cod sursa(job #1922804)

Utilizator jurjstyleJurj Andrei jurjstyle Data 10 martie 2017 18:59:19
Problema Ciclu Eulerian Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 2.43 kb
#include <fstream>
#include <vector>
#include <stack>

using namespace std;

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

/*
    Deoarece trebuie sa stergem muchiile cat se poate de repede,
    Nu vom memora la fel graful
    G[x] .. va contine nr in ordinea citirii muchiilor
    Begin[i] si End[i] vor fi a i-a muchie
    Vectorul bool pt a marca daca a fost/sau nu folosita
*/
vector <int> G[100005];
int Begin[500005], End[500005];
bool Muchie_Folosita[500005];
bool Viz[100005];
vector <int> Ans;
stack <int> Stk;
int N, M;

void DFS(int node)
{
    Viz[node] = 1;
    for (const int & x : G[node])
    {
        int dest;
        if (node == End[x])
            dest = Begin[x];
        else
            dest = End[x];
        if (Viz[dest] == 0)
            DFS(dest);
    }
}

int main()
{
    f >> N >> M;
    for (int i = 0; i < M; ++i)
    {
        int x, y;
        f >> x >> y;
        G[x].push_back(i);
        G[y].push_back(i);
        Begin[i] = x;
        End[i] = y;
    }
    //verificam grad par
    for (int i = 1; i <= N; ++i)
        if (G[i].size() % 2 == 1)
        {
            g << "-1";
            return 0;
        }
    //verificam conexitate
    DFS(1);
    for (int i = 1; i <= N; ++i)
        if (Viz[i] == 0)
        {
            g << "-1";
            return 0;
        }
    //daca am ajuns aici, sigur putem construi un ciclu eulerian
    Stk.push(1); //incepem cu nodul 1 ca nu conteaza intr-un ciclu
    while (!Stk.empty())
    {
        int node = Stk.top();
        if (!G[node].empty()) //daca mai avem muchii
        {
            int edge = G[node].back(); //scoatem ultima muchie
            G[node].pop_back();
            if (!Muchie_Folosita[edge]) //daca n-a fost folosita
            {
                Muchie_Folosita[edge] = 1; //o folosim
                int dest; //aflam din ce parte in ce parte mergem
                if (node == Begin[edge])
                    dest = End[edge];
                else
                    dest = Begin[edge];
                Stk.push(dest); //introducem nodul in stiva
            }
        }
        else //am terminat cu nodul respectiv, il eliminam si il introducem in raspuns
        {
            Stk.pop();
            Ans.push_back(node);
        }
    }
    for (int i = 0; i < Ans.size() - 1; ++i)
        g << Ans[i] << " ";
    f.close();
    g.close();
    return 0;
}