Cod sursa(job #1025530)

Utilizator raulmuresanRaul Muresan raulmuresan Data 10 noiembrie 2013 10:42:43
Problema Ciclu Eulerian Scor 80
Compilator cpp Status done
Runda Arhiva educationala Marime 3.11 kb
#include <cstdio>
#include <algorithm>
#include<vector>
#include<queue>
#include<list>
#include<stack>

using namespace std;

int grad[100009],y,nod,minim,i,aux,n,k,x2,x1,j,p,s,unu,t,m,doi,x,st,dr,maxi,sol,maxi2,ok;
vector < int > v[100010];
list <int> a[100010];
stack <int>stiva;

vector<int> circuit;
int viz[100009];

queue<int > q;
 int eulerian()
 {
     int i;
    for(i=1;i<=n;i++)
    {
        if(grad[i]%2==1)
        {
            return 0;
        }
    }
    for(i=1;i<=n;i++)
    {
        viz[i]=-1;

    }


    q.push(1);
    //verificam conexitatea grafului
     while(! q.empty())
    {
        nod=q.front();
        q.pop();
        //printf("%d ",nod);
        for(i=0;i<v[nod].size();i++)
        {
            //printf("%d %d\n",nod,v[nod][i]);
            if(viz[v[nod][i]]==-1)
            {
                viz[v[nod][i]]=1;
                q.push(v[nod][i]);
            }
        }
    }
    for(i=2;i<=n;i++)
    {
        if(viz[i]==-1)
        return 0;
    }
    return 1;

 }

 void sterge(int nod, int vecin) {
    //graph[node].pop_front();//sterg sageata din node -> neighbour
    a[nod].pop_front();
    list<int>::iterator it;
    for (it = a[vecin].begin(); it != a[vecin].end(); ++it)//caut neighbour -> node
        if (*it == nod) {//cand gasesc
            a[nod].erase(it);//sterg; it = pointer catre node
            break;//opresc cautarea
        }
}

 void euler(int nod) {//lucrez cu o componenta circulara disjuncta (fata de alte componente)
    int vecin;
    while(! a[nod].empty())
    {
        //printf("%d ",nod);
        vecin=a[nod].front();
        stiva.push(nod);
        sterge(nod,vecin);
        nod=vecin;
    }

    /*while (!graph[node].empty()) {//pentru cazul in care avem self-loops, repetam.
        //daca node nu mai are vecini, stim ca am ajuns in root, deci am inchis circuitul
        //asa ca incercam sa deschidem un alt circuit (care urmeaza sa fie integrat)
        //dintr-un nod cu vecini (daca nu gasim astfel de noduri, terminam; vezi solve())
        neighbour = graph[node].front();
        stiva.push(node);
        sterge(node, neighbour);//sterg muchia dintre node si neighbour
        node = neighbour;
    }*/
}

void solve() {
    int nod = 1;
    do {
        euler(nod);
        nod = stiva.top();
        stiva.pop();
        circuit.push_back(nod);//pentru vizibilitate, copiem nodurie circuitului intr-un vector
    }while (!stiva.empty());
}
void write()
{
    for(i=0;i<circuit.size();i++)
    {
        printf("%d ",circuit[i]);
    }
}

int main()
{
    freopen ("ciclueuler.in","r",stdin);
    freopen ("ciclueuler.out","w",stdout);
    scanf("%d%d",&n,&m);
    for(i=1;i<=m;i++)
    {
        scanf("%d %d",&x,&y);
       // printf("%d %d\n",x,y);
        v[x].push_back(y);
        v[y].push_back(x);
        a[x].push_back(y);
        a[y].push_back(x);

        grad[x]++;
        grad[y]++;
    }
    //verifciam daca graful este eulerian
    if(eulerian() == 1)
    {
        solve();
        write();

    }
    else printf("-1");



}