Cod sursa(job #882089)

Utilizator DianaEllenaDiana Elena DianaEllena Data 18 februarie 2013 21:25:46
Problema Ciclu Eulerian Scor 60
Compilator cpp Status done
Runda Arhiva educationala Marime 2.74 kb
#include <fstream>
#include <vector>
using namespace std;
ifstream fin("ciclueuler.in");
ofstream fout("ciclueuler.out");

struct NOD
{
	int inf;
	struct NOD* urm;
};
typedef struct NOD* Lista;
Lista C1,C2,u1,u2;

int n,m;
vector<int> a[100008];
bool viz[100008];
int nrmuchii;
int gr[100008];

void citire();
void dfs(int k);
bool conex();
void det_ciclu();
int ciclu(Lista &C,int x,Lista &u);
void afisare();

int main()
{
    citire();
    //caut un vf neizolat
    if(conex())
    {
        det_ciclu();
        afisare();
    }
    else fout<<"Nu este eulerien";
    fout.close();
    return 0;
}

void citire()
{
    int i,x,y;
    fin>>n>>m;
    for(i=1;i<=m;i++)
        {
            fin>>x>>y;
            a[x].push_back(y); a[y].push_back(x);
            gr[x]++; gr[y]++;
        }
}

bool conex()
{
    int i,x;
    //caut un vf neizolat
    for(x=1;x<=n&&!gr[x];x++);
    if(x>n) return 1;

    dfs(x);
    for(i=1;i<=n;i++) //verific daca au mai ramas vf nevizitate si neizolate
       if(viz[i]==0 && gr[i]) return 0;

    //verific daca toate gradele sunt pare
    for(i=1;i<=n;i++)
        if(gr[i]%2==1) return 0;

    return 1;
}

void dfs(int k)
{
    int i;
    viz[k]=true;
    for(i=0;i<a[k].size();i++)
            if(viz[a[k][i]]==0)
                dfs(a[k][i]);
}

void det_ciclu()
{
    Lista p,q;
    int x,nr2=0;
    //caut un vf cu gradul nenul
    for(x=1;x<=n&&!gr[x];x++);
    nrmuchii=ciclu(C1,x,u1);

    while(nrmuchii<m)
    {
        //caut pe C1 un vf cu gradul nenul
        for(p=C1;!gr[p->inf];p=p->urm);

        //acum p indica un vf cu gradul nenul
        nr2=ciclu(C2,p->inf,u2);

        //reunesc ciclul C1 cu cilcul C2
        q=p->urm;
        p->urm=C2->urm; u2->urm=q;
        nrmuchii+=nr2;
    }
}

int ciclu(Lista &C,int x,Lista &u)
{
    int y,uvf,lg=0,i;
    Lista p;
    p=new NOD;
    p->inf=x; p->urm=NULL;
    C=u=p;

    do
    {
        //caut un vf adiacent cu ultimul vf din lista
       uvf=u->inf;
       //parcurg linia uvf pana sau de un y adiacent cu el
       for(i=0;!a[uvf][i]&&i<a[uvf].size();i++);
       y=a[uvf][i];
        //adaug muchia [uvf,y] in cilcu eulerien
        //aloc memorie pentru un nou vf
        p=new NOD; p->inf=y; p->urm=NULL;
        //il adaug la sfarsitul ciclului
        u->urm=p; u=p;
        lg++;
        //am folosit aceasta muchie, o elimin din graf
        a[uvf][i]=0;
        for(i=0;i<a[y].size();i++)
            if(a[y][i]==uvf)
            {
                a[y][i]=0; break;
            }
        gr[uvf]--; gr[y]--;
      }
    while(y!=x);
    return lg;
}

void afisare()
{
    Lista p;
    for(p=C1;p;p=p->urm)
        fout<<p->inf<<" ";

}