Cod sursa(job #882393)

Utilizator siriteanu_andreisiriteanu andrei siriteanu_andrei Data 19 februarie 2013 06:39:48
Problema Ciclu Eulerian Scor 0
Compilator cpp Status done
Runda Arhiva educationala Marime 2.82 kb
#include <fstream>
#define NMax 10001
using namespace std;
ifstream fin("ciclueulerian.in");
ofstream fout("cilcueulerian.out");
 
struct Nod
{
    int vf;
    struct Nod * urm;
};
typedef struct Nod * Lista;
Lista c1,c2,sfc1,sfc2;
 
int n,m;
int d[NMax],viz[NMax];
int a[NMax][NMax];

void dfs(int x);
void det_eulerian();
bool conex();
int gradepare();
void afisare_ciclu();
int ciclu(int, Lista&, Lista&);
 
int main()
{
    int i,x,y;
    fin>>n>>m;
    for(i=1;i<=m;i++)
    {
        fin>>x>>y;
        d[x]++;
        d[y]++;
        a[x][y]=a[y][x]=true;
    }
    if(conex() && gradepare())
    {
        det_eulerian();
        afisare_ciclu();
    }
    else
        fout<<"-1"<<'\n';
    fout.close();
    return 0;
}
  
void dfs(int x)
{
    int i;
    viz[x]=true;
    for(i=1;i<=n;i++)
        if(!viz[i] && a[x][i])
            dfs(i);
}
 
bool conex()
{
    int x,i;
    //caut un varf neizolat
    for(x=1;x<=n && !d[x];x++);
    if(x>n)
        return 1;
    //i este vf neizolat
    dfs(x);
    for(i=1;i<=n;i++) //verific daca au mai ramas varfuri nevizitate si neizolate
        if(!viz[i] && d[i])
            return 0;
    return 1;
}
 
int gradepare()
{
    int i;
    for(i=1;i<=n;i++)
        if(d[i]%2)
            return 0;
    return 1;
}
 
void det_eulerian()
{
    int x,nr2,total=0;
    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 vf cu gradul nenul
        for(p=c1;!d[p->vf];p=p->urm);
        //acum p indica in vf cu gradul nenul
        //contsruiesc al doilea ciclu
        nr2=ciclu(p->vf,c2,sfc2);
        //reunesc ciclul 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,uvf,lg=0;//uvf-ult nod din lista
    //incep ciclul cu vf x
    //aloc memorie pt un nod
    p=new Nod;
    p->vf=x;
    p->urm=NULL;
    c=sfc=p;//el este singurul, primul, ultimul
    do
    {
        //caut y, un varf adiacent cu ultimul varf din lista
        uvf=sfc->vf;
        //parcurg linia uvf pana dau de un y adiacent cu el
        for(y=1;!a[uvf][y];y++)
        //adaug muchia [uvf, y] in ciclul eulerian
        //aloc memorie pt un nou vf
        p=new Nod;
        p->vf=y;
        p->urm=NULL;
        //il adaug la sfarsitul ciclului
        sfc->urm=p;
        sfc=p;
        lg++;
        //am folosit aceasta muchie si o elimin din graf
        a[uvf][y]=a[y][uvf]=false;
        d[y]--;
        d[uvf]--;
    }
    while(y!=x);
    return lg;
}
 
void afisare_ciclu()
{
    Lista p;
    for(p=c1;p;p=p->urm)
        fout<<p->vf<<' ';
    fout<<'\n';
}