Cod sursa(job #488120)

Utilizator ariel_roAriel Chelsau ariel_ro Data 27 septembrie 2010 18:33:51
Problema Ciclu Eulerian Scor 10
Compilator cpp Status done
Runda Arhiva educationala Marime 2.56 kb
#include <iostream>
#include <fstream>
#include <stdlib.h>

#define NMAX 100005

using namespace std;
struct Nod
{
    int elem;
    Nod *adr_urm;
};

Nod *L[NMAX], *pSol, *uSol;
FILE *in = fopen("ciclueuler.in", "r");
FILE *out = fopen("ciclueuler.out", "w");
int s[NMAX], grad[NMAX], N, M;

void df(int nod)
{
    Nod *p;
    //cout<<nod<<" ";
    p = L[nod];
    s[nod] = 1;
    while (p)
    {
        if (s[p->elem] == 0)
            df(p->elem);
        p = p->adr_urm;
    }
}

bool este_conex()
{
    df(1);
    for (int i = 1; i <= N; i++)
        if (s[i] == 0)
            return false;
    return true;
}

bool eulerian()
{
    if (!este_conex())
        return false;
    else
    {
        for (int i = 1; i <= N; i++)
            if (grad[i] % 2)
                return false;
        return true;
    }
}

void citire_graf_lista(Nod *L[NMAX], int grad[NMAX])
{
    int n1, n2;
    Nod *p1, *p2;
    fscanf(in, "%d %d", &N, &M);
    for (int i = 1; i <= M; i++)
    {
        fscanf(in, "%d %d", &n1, &n2);
        p1 = new Nod; p1->adr_urm = L[n1]; p1->elem = n2; L[n1] = p1;
        grad[n1]++;

        p2 = new Nod; p2->adr_urm = L[n2]; p2->elem = n1; L[n2] = p2;
        grad[n2]++;
    }
}

void sterge(int v, int u)
{
    Nod *q1 = (L[v]->adr_urm) ? L[v]->adr_urm : 0;
    L[v] = q1; // sterge in sensul v->u

    Nod *q; // sterge in sensul u->v
    if (L[u]->elem == v)
    {
        q = L[u];
        L[u] = L[u]->adr_urm;
    }
    else
    {
        Nod *p = L[u];
        while (p->adr_urm->elem != v)
            p = p->adr_urm;

        q = p->adr_urm;
        p->adr_urm = q->adr_urm;
    }

    delete q;
}

// gaseste cicluri disjuncte
void adauga(int inceput)
{
    int curent = -1, v, index;

    index = inceput;
    while (curent != inceput) {
        Nod *p = L[index];
        // construirea drumului
        Nod *nod_gasit = new Nod;
        nod_gasit->elem = p->elem;
        nod_gasit->adr_urm = 0;
        uSol->adr_urm = nod_gasit;
        uSol = nod_gasit;

        v = p->elem;
        sterge(index, v);
        index = curent = v;
    }

    Nod *p = pSol;
    while (p->adr_urm) // fara ultimul element
    {
        fprintf(out, "%d ", p->elem);
        p = p->adr_urm;
    }
}

int main()
{
    citire_graf_lista(L, grad);
    if (eulerian())
    {
        pSol = new Nod;
        pSol->elem = 1; pSol->adr_urm = 0;
        uSol = pSol;
        adauga(1);
    }
    else
        cout<<-1<<endl;
    fclose(in);
    fclose(out);
}