Cod sursa(job #1333391)

Utilizator bullseYeIacob Sergiu bullseYe Data 3 februarie 2015 09:07:06
Problema Ciclu Eulerian Scor 0
Compilator cpp Status done
Runda Arhiva educationala Marime 2.93 kb
#include <cstdio>
#define NMAX 1001
using namespace std;

struct nod{
    int vf;
    struct nod *urm;
};

typedef struct nod *Lista;

int n, m, nr;
bool G[NMAX][NMAX];
int d[NMAX];
int uz[NMAX];
Lista C1, C2;

void citire();
bool conex(int vf);
bool grade_pare();
void afisare (bool);
int det_ciclu (int, Lista&);
int det_varf ();
void unific (Lista&, Lista);
void inserare (int, Lista&);
int caut_vf_adiacent (int);

int main()
{
    int nr, nr2, z;
    citire();
    if (conex(1) && grade_pare())
    {
        nr=det_ciclu (1, C1);//returneaza nr de muchii din ciclu
        while (nr<m)//ciclul nu este eulerian inca
        {
            z=det_varf();//C1 va indica nodul care il preceda pe z
            nr2=det_ciclu (z, C2);
            unific (C1, C2);
            nr+=nr2;
        }
        afisare (true);
    }
        else
        afisare (false);
    return 0;
}

void afisare (bool good)
{
    Lista p=C1;
    FILE*fout=fopen ("eulerian.out", "w");
    if (!good)
        fprintf(fout, "Graful nu este eulerian!");
        else
        do
        {
            fprintf(fout, "%d ", p->vf);
            p=p->urm;
        }
        while (p!=C1);
    fprintf(fout, "%d", C1->vf);
    fprintf(fout, "\n");
    fclose (fout);
    return;
}

void citire()
{
    int a, b, i;
    FILE*fin=fopen ("eulerian.in", "r");
    fscanf(fin, "%d %d", &n, &m);
    for (i=1; i<=m; ++i)
    {
        fscanf(fin, "%d %d", &a, &b);
        G[a][b]=G[b][a]=1;
        ++d[a];
        ++d[b];
    }
    fclose (fin);
    return;
}

bool conex (int vf)
{
    int i;
    uz[vf]=1; ++nr;
    if (nr==n)
        return true;
    for (i=1; i<=n; ++i)
        if (G[vf][i] && !uz[i])
            conex (i);
    return nr==n;
}

bool grade_pare()
{
    int i;
    for (i=1; i<=n; ++i)
        if (d[i]%2)
            return false;
    return true;
}

int det_ciclu (int x, Lista &C)
{
    int y, nr=0;
    C=NULL;
    inserare (x, C);
    do
    {
        y=caut_vf_adiacent(C->vf);
        if (x!=y)
            inserare (y, C);
        ++nr;
    }
    while (y!=x);
    return nr;
}

void inserare (int x, Lista &C)
{
    Lista p=new nod;
    p->vf=x;
    if (!C)
        p->urm=p;
        else
        {
            p->urm=C->urm;
            C->urm=p;
        }
    C=p;
}

int caut_vf_adiacent (int x)
{
    int i;
    for (i=1; i<=n; ++i)
        if (G[x][i])
        {
            G[x][i]=0;
            G[i][x]=0;
            --d[i];
            --d[x];
            return i;
        }
    return 0;
}

int det_varf()//returnez un varf din C1 care are muchii incidente cu el
{
    Lista p, q;
    for (p=C1->urm, q=C1; p; q=p, p=p->urm)
        if (d[p->vf])
    {
        C1=q;
        return p->vf;
    }
    return -1;
}

void unific (Lista &C1, Lista C2)
{
    Lista p;
    p=C1->urm;
    C1->urm=C2->urm;
    C2->urm=p;
    return;
}