Cod sursa(job #2504211)

Utilizator juniorOvidiu Rosca junior Data 4 decembrie 2019 17:17:34
Problema Ciclu Eulerian Scor 0
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 2.19 kb
// pentru graf "normal"

#include <fstream>
#include <iostream>

using namespace std;

ifstream fin ("ciclueuler.in");
ofstream fout ("ciclueuler.out");
int n, ni, ms, m, nc, nu, pni, i, nec, g[1000], p, c[1000], cnou[1000];
bool a[1000][1000];

void inserare (int p, int l) { // p - pozitia incepand de la care se insereaza
  for (i = nec; i >= p; i--)
    c[i + l] = c[i];
  for (i = 1; i <= l; i++) // l - lungimea noului ciclu
    c[i + p - 1] = cnou[i];
  nec += l; // sa verificam ce se intampla daca nu facem operatia!
}
/*         3 4
c    : 1 2 6             1
cnou :       3       4 6
cnou :         5 7 3
*/
/*
 i     x
----------
 1     p
 2    p+1  ==> x-i = p-1 ==> x = p-1+i
 3    p+2
 */
void citire () {
  int l, c, i;
  fin >> n >> m;
  for (i = 1; i <= m; i++) {
    fin >> l >> c;
    a[l][c] = a[c][l] = true; g[l]++; g[c]++; // adiacenta, grade
  }
}

int vecin (int nc) {
  int v;
  for (v = 1; not a[nc][v]; v++); // Cat timp nu este vecin, il marim pe v.
  return v;
}

int main () {
  citire();
  ni = 1;                                 // nodul initial
  while (ms < m) {                        // cat timp nu s-au selectat toate muchiile
    i = 0; nc = ni;
    do {                                  // Determinam un ciclu mic.
      nu = vecin (nc);                    // nodul urmator
      g[nu]--; g[nc]--;                   // scad gradele pt ca  muchia nu mai exista
      a[nu][nc] = a[nc][nu] = false;      // consumam muchia [nc,nu]
      ms++;                               // Selectam inca o muchie.
      nc = nu;                            // nodul curent pentru pasul urmator
      cnou[++i] = nc;                     // punem inca un nod in ciclul curent
    } while (nc != ni);
    if (c[1] != 0)                        // Am determinat cel putin un ciclu.
      for (pni = 1; c[pni] != ni; pni++);
    inserare (pni + 1, i);
    if (ms < m)
      for (i = 1; g[c[i]] == 0; i++);     // Gasim nodul cu care va incepe un nou ciclu.
    ni = c[i];                            // nodul initial pentru ciclul urmator
  }
  fout << 1 << ' ';
  for (i = 1; i <= m; i++)                // Afisare
    fout << c[i] << ' ';
  return 0;
}