Cod sursa(job #2820884)

Utilizator Andreea__Zavoiu Andreea Andreea__ Data 21 decembrie 2021 20:19:36
Problema Ciclu Eulerian Scor 0
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 2.29 kb
// trece prin fiecare MUCHIE exact o singura data <=> este conex si toate nodurile sale au grad par
#include <iostream>
#include <fstream>
#include <vector>
#include <stack>
#include <unordered_map>
#define nMax 100001
#define mMax 500001
using namespace std;

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

int n, m, viz[nMax], grad[nMax], sters[mMax]; // retin ce muchii am sters (numerotez muchiile in ordinea citirii in la[i].second)
vector<pair<int,int>> la[nMax]; // multigraf = is permitted to have multiple edges => two vertices may be connected by more than one edge
   // pt x: (y, indice_muchie)    <=>  muchia [x,y] (multigraf neorientat) citita pe locul indice_muchie
unordered_map<int,int> edge_count;// edge_count represents the number of edges emerging from a vertex
stack<int> s;   // folosesc stiva pentru a retine ciclul eulerian


void dfs(int x)
{
    viz[x] = 1;
    for (auto vecin: la[x])
        if (!viz[vecin.first])
            dfs(vecin.first);
}

void euler(int x)
{
    while (!la[x].empty())  // cat timp am muchii din x
    {
            // retin (ultimul) vecin al lui x => (y, nr_muchie) = (la[x].back().first, la[x].back().second)
            int urm = la[x].back().first;
            int nrMuchie = la[x].back().second;
            sters[nrMuchie] = 1;  // marchez ca muchia a fost parcursa
            la[x].pop_back();  // o elimin
            euler(urm);  // recursiv pt vecin

    }
    s.push(x);
}


int main()
{
    int x, y, nr_muchie = 0;
    fin >> n >> m;

    for (int i=0; i<m; i++)
    {
        nr_muchie++;
        fin >> x >> y;
        la[x].push_back(make_pair(y, nr_muchie));
        la[y].push_back(make_pair(x, nr_muchie)); // neorientat
    }

    dfs(1);

    for (int i=1; i<=n; i++)
    {
        edge_count[i] = la[i].size(); //find the count of edges to keep track of unused edges

        // verif propr de graf eulerian: toate nodurile trb sa aiba grad par
        if (edge_count[i]%2==1) // daca se incalca , inchei
        {
            fout << -1;
            return 0;
        }
    }

    euler(1);

    while (!s.empty())
    {
        if (s.size() >= 2) // primul si ultimul element e acelasi, pt ca am facut ciclu => afisez pana la primul elem pus pe stiva ca sa nu-l repet
            fout << s.top() << " ";
        s.pop();
    }

    return 0;
}