Cod sursa(job #1573638)

Utilizator mariusmagureanmagurean marius mariusmagurean Data 19 ianuarie 2016 20:27:47
Problema Ciclu Eulerian Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 2.37 kb
//verifica daca un graf neorientat este eulerian si, in caz afirmativ, afiseaza un cilcu eulerian
#include<fstream>
#include<vector>
#include<algorithm>
#include<stack>

#define Dim 100001
#define pb push_back
#define out pop_back
using namespace std;

ifstream fin("ciclueuler.in");
ofstream fout("ciclueuler.out");
//matricea v retine graful, dar linia i retine doar nodurile care formeaza muchie cu i
//vectorul sol retine un ciclu eulerian
//stiva st retine extremitatea finala a muchiei parcurse
//n -nr noduri, m-nr muchii, x,y extremitatile unei muchii, grad - gradul fiecarui nod
vector<int> v[Dim],sol;
stack<int> st;
int n,m,x,y,grad[Dim];

void citire()
{
    fin>>n>>m;
    while(m!=0)
    {
        fin>>x>>y;
        v[x].pb(y);
        v[y].pb(x);
        grad[x]++;
        grad[y]++;
        m--;
    }
    fin.close();
}

void eulerian()
{
    //pornesc cautarea de la nodul 1
    //pun in stiva acest nod
    st.push(1);
    //cat timp stiva nu este goala
    while(st.empty()==false)
    {
        //extrag varful stivei, adica extremitatea finala a muchiei parcurse
        //va trebui sa caut o muchie din graf neparcursa care sa aiba aceasta val ca extremitate initiala
        x=st.top();
        //daca linia lui x mai are valori, inseamna ca mai sunt muchii de parcurs
        if(v[x].size()!=0)
        {
            //retin ultimul nod de pe linia x
            y=v[x][v[x].size()-1];
            //il elimin, considerandu-l parcurs
            v[x].out();
            //il introduc in stiva in vederea gasirii urmatoarei muchii de parcurs
            st.push(y);
            //sterg nodul x din lista lui y
            //practic, am parcurs muchia (x,y) si atunci elimin din graf (x,y) si (y,x)
            v[y].erase(find(v[y].begin(),v[y].end(),x));
        }
        else
        {
            //daca linia x este vida inseamna ca x face parte din ciclu si il retin in sol
            sol.pb(x);
            //scot aceasta valoare din stiva
            st.pop();
        }
    }
}

int main()
{
    citire();
    int i;
    //un graf este eulerian daca toate gradele sunt pare
    for(i=1;i<=n;i++)
        if(grad[i]%2==1)
        {
            fout<<-1;
            return 0;
        }
    eulerian();
    sol.out();
    for(i=0;i<sol.size();i++)
        fout<<sol[i]<<" ";
    fout.close();
    return 0;
}