Cod sursa(job #251335)

Utilizator otilia_sOtilia Stretcu otilia_s Data 2 februarie 2009 12:48:48
Problema Ciclu Eulerian Scor 20
Compilator cpp Status done
Runda Arhiva educationala Marime 1.95 kb
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#define NMAX 1001
#define MMAX 50001
int S[NMAX],L[NMAX],A[NMAX][NMAX],grad[NMAX],col[NMAX];
int n,m,ns,nl;

void citire()
{ int i,x,y;
 FILE *fin=fopen("ciclueuler.in","r");
 fscanf(fin,"%d%d",&n,&m);
 memset(grad,0,sizeof(grad));
 for (i=1;i<=m;i++)
  {
   fscanf(fin,"%d %d",&x,&y);
   A[x][0]++;
   A[x][A[x][0]]=y;
   A[y][0]++;  
   A[y][A[y][0]]=x;
   grad[x]++; grad[y]++;
  }
 fclose(fin);
}

void bfs(int v)
{
 int Q[NMAX],p,u,nr=1;
 p=u=0; Q[0]=v; col[v]=1;
 while (p<=u&&nr<n)
  {
   v=Q[p++];
   for (int i=1;i<=A[v][0];i++)
    if (!col[A[v][i]])
		 {
		  col[A[v][i]]=1; nr++;
		  Q[++u]=A[v][i];
		 }
  }
}

int este_conex()
{
 bfs(1);
 for (int v=1;v<=n;v++)
  if (!col[v]) return 0;
 return 1;
}

int eulerian()
{
 if (!este_conex()) return 0;
 for (int i=1;i<=n;i++)
  if (grad[i]%2) return 0;
 return 1;
}

void sterge(int v, int w)
{
 int h;
 grad[v]--; grad[w]--;
 int poz=0;
 for (h=1;h<=A[v][0]&&!poz;h++)
  if (A[v][h]==w) poz=h;
 for (h=poz;h<A[v][0];h++)
  A[v][h]=A[v][h+1];
 A[v][0]--;

 poz=0;
 for (h=1;h<=A[w][0]&&!poz;h++)
  if (A[w][h]==v) poz=h;
 for (h=poz;h<A[w][0];h++)
  A[w][h]=A[w][h+1];
 A[w][0]--;
}

void euler(int v)
{
 while (1)
  {
   if (!A[v][0]) { break; }//nu mai are vecini
   int w=A[v][1];
   S[++ns]=v;
   sterge(v,w);
   v=w;
  }
}

int rez()
{
 int v=eulerian(); //verifica daca este graf eulerian
 if (!v) return -1;
 ns=0; //nr de elem din stiva
 do
  {
   euler(v);
   v=S[ns]; ns--;
   L[++nl]=v; //Lista cu ciclul final care are nl elemente
  }
 while (ns); //cat timp stiva nu este vida
 return 1;
}

void afisare(int x)
{
 FILE *fout=fopen("ciclueuler.out","w");
 if (x==-1) fprintf(fout,"-1\n");
    else
    {
     for (int i=nl;i>0;i--)
      fprintf(fout,"%d ",L[i]);
    }
 fclose(fout);
}

int main()
{
 citire();
 afisare(rez());
 return 0;
}