Cod sursa(job #688270)

Utilizator matemariaescuMaria Mateescu matemariaescu Data 23 februarie 2012 13:23:51
Problema Ciclu Eulerian Scor 60
Compilator cpp Status done
Runda Arhiva educationala Marime 2.33 kb
// fie g un graf neorientat fara varfuri izolate
// g este eulerian daca si numai daca
// g conex
// gradele varfurilor sunt pare

# include <cstdio>
# include <vector>

using namespace std;

struct Nod 
{
  int inf;
  Nod * urm;
};

typedef Nod* Lista;

Lista C1,C2,y,last,last2;
int x0,i,n,m,viz;
vector <int> g[100100];

void ciclu (Lista & C, Lista & last, int primul);

void citire ()
{
  int i, x, y;
	scanf("%d%d",&n,&m);
  for (i=1;i<=n;i++)
    g[i].push_back(0);
	for (i=0; i<m; i++)
	{
		scanf ("%d%d",&x,&y);
		g[x][0]++; g[x].push_back(y);
    g[y][0]++; g[y].push_back(x);
	}
}

int main ()
{
  freopen ("ciclueuler.in","r",stdin);
  freopen ("ciclueuler.out","w",stdout);
  citire();
  // reprezentare graf prin lista de adiacenta
  for (i=1;i<=n;i++)
  {
    if (g[i][0]%2==1)
    {
      printf("Nu e eulerian");
      return 0;
    }
  }
  //alegem un varf al grafului 1 de obicei
  // construiesc un ciclu c1 plecand din varful ales
  // (la fiecare pas aleg o muchie care nu a mai fost aleasa si care e incidenta cu ultimul varf ales
    // dupa un anumit numar de pasi voi reveni la vf initial inchizand ciclul)
  //daca e eulerian stop. Daca nu:
  // aleg un varf de pe ciclul c1 care este incident cu o muchie care nu a mai fost selectata
  // din vf ala incep sa construiesc ciclul c2 prin acelasi procedeu apoi reunesc cele doua
  // repet
  
  // am nevoie de: vector viz pentru muchii SAU cand utilizam in lista de adiacenta pun -1
  // obs daca este multigraf ster o aparitie nu toate
  x0=1;
  // ciclu unu
  ciclu(C1,last,x0);
  i=1; y=C1;
  while (viz<m)
  {
    for (;y!=last;y=y->urm)
      if (g[y->inf][0]>0)
        {ciclu(C2,last2,y->inf);break;}
    last2->urm=y->urm;
    y->urm=C2->urm;
  }
  for (y=C1;y!=last;y=y->urm)
        {printf("%d ",y->inf);}
  
  return 0;
}

void ciclu (Lista & C, Lista & last, int primul)
{
  Lista x;
  int i;
  C=new Nod;
  C->inf=primul;
  C->urm=NULL;
  last=C;
  do
  {    
    x=new Nod;
    viz++;
    
    x->inf=g[last->inf][1];
    last->urm=x;
    g[last->inf][1]=g[last->inf][g[last->inf][0]];
    g[last->inf][0]--;
    i=1;
    while (g[x->inf][i]!=(last->inf))
      i++;
    g[x->inf][i]=g[x->inf][g[x->inf][0]];
    g[x->inf][0]--;
    x->urm=NULL;
    last=x;
  }
  while(last-> inf!=C->inf);
}