Cod sursa(job #882084)

Utilizator CodrynhoLupascu Codrin Codrynho Data 18 februarie 2013 21:15:36
Problema Ciclu Eulerian Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 3.16 kb
#include<fstream>
#include<vector>
#define DMAX 100005

using namespace std;

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

struct nod
{
    int vf;
    struct nod *urm;
};
typedef struct nod * Lista;
Lista C1, C2, sfC1, sfC2;

void citire();
void dfs(int x);
void determina_ciclu();
void afisare();
bool conex();
int gradepare();
int ciclu(int x, Lista& C, Lista& sfC);

vector<int>G[DMAX];
bool viz[DMAX];
int d[DMAX];
int n ,m;

int main()
{
    citire();
    if(conex() && gradepare())
    {
        determina_ciclu();
        afisare();
    }
    else
        fout << "-1" << '\n';
    fout.close();
    return 0;
}

bool conex()
{
    int i;
    //caut un varf neizolat
    for(i=1;i<=n && !d[i];i++);
    if(i>n)
        return 1;
    //i este varf neizolat
    dfs(i);
    for(i=1;i<=n;i++)
        if(!viz[i] && d[i])
            return 0;
    return 1;
}

void dfs(int x)
{
    unsigned i;
    viz[x]=true;
    for(i=0;i<G[x].size();i++)
        if(!viz[G[x][i]])
            dfs(G[x][i]);
}

int gradepare()
{
    int i;
    for(i=1;i<=n;i++)
        if(d[i]%2)
        return 0;
    return 1;
}

void citire()
{
    int x, y, i;
    fin >> n >> m;
    for(i=1;i<=m;i++)
    {//liste de adiacenta
        fin >> x >> y;
        d[x]++;
        d[y]++;
        G[x].push_back(y);
        G[y].push_back(x);
    }
}

void determina_ciclu()
{
    int x, nr2, total;
    Lista p, q;
    //caut un varf cu gradul nenul
    for(x=1;x<=n && !d[x];x++);
    //x are gradul nenul
    total=ciclu(x, C1, sfC1);
    while(total<m)
    {
        //caut pe C1 un varf cu gradul nenul
        for(p=C1; !d[p->vf]; p=p->urm);
        //acum p indica un varf cu grad nenul
        nr2=ciclu(p->vf, C2, sfC2);
        //reunesc ciclu C1 cu ciclul C2
        q=p->urm;
        p->urm=C2->urm;
        sfC2->urm=q;
        total+=nr2;
    }
}

int ciclu(int x, Lista& C, Lista& sfC)
{
    Lista p;
    int y, lg, vf_ultim;//ultimul vf din lista
    unsigned i, j;
    //incep ciclu cu vf x
    //aloc memorie pt un nod
    lg=0;
    p=new nod;
    p->vf=x; p->urm=NULL;
    C=sfC=p;// el este primul, ultimul, singurul nod din lista
    do
    {
        //caut y, un vf adiacent cu ultimul varf din lista
        vf_ultim=sfC->vf;
        //parcurg linia vf_ultim pana dau un y adiacent cu el
        for(i=0; i<G[vf_ultim].size();i++)
            if(G[vf_ultim][i])
                break;
        y=G[vf_ultim][i];
        //adaug muchia [vf_ultim,y] in ciclu eulerian
        //aloc memorie
        p=new nod;
        p->vf=y;
        p->urm=NULL;
        //il adaug la sfarsitul ciclului
        sfC->urm=p;
        sfC=p;
        lg++;
        //am folosit aceasta muchie, o elimin din graf
        G[vf_ultim][i]=0;
        for(j=0;j<G[y].size();j++)
            if(G[y][j]==vf_ultim)
            {
                G[y][j]=0;
                break;
            }
        d[vf_ultim]--;
        d[y]--;
    }
    while(y!=x);
    return lg;
}

void afisare()
{
    Lista p;
    for(p=C1; p!=NULL ;p=p->urm)
        fout << p->vf << ' ';
    fout<<'\n';
}