Cod sursa(job #3256913)

Utilizator alex_0747Gheorghica Alexandru alex_0747 Data 16 noiembrie 2024 11:31:57
Problema Ciclu Eulerian Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 1.7 kb
#include <bits/stdc++.h>
using namespace std;

/**
Grafuri euleriene

Un ciclu eulerian intr-un graf este un ciclu (nu neaparat elementar)
care trece prin toate muchiile.

Un graf este eulerian daca are un ciclu eulerian.

Un graf este eulerian daca si numai daca, eliminand eventualele
noduri izolate, graful este conex, iar gradele tuturor nodurilor
sunt pare.

Algoritmul lui Householder
*/
ifstream fin("ciclueuler.in");
ofstream fout("ciclueuler.out");
int n, m, X[500001], Y[500001];
vector<int> L[100001]; /// L[i]: L[i][0], L[i][1], ..., L[i][]
/// L[i] = retine indicii muchiilor care au un capat in nodul i
int e[500009], len;
/// in e retinem ciclul eulerian
int viz[500001]; /// viz[i] = 1, daca muchia (X[i], Y[i]) a fost folosita
int d[100001]; /// d[i] = gradul lui i
int ind[100001];
/// ind[i] = retine pozitia din lista L[i] unde ne aflam

void Citire()
{
    int i, j;
    fin >> n >> m;
    for (int p = 1; p <= m; p++)
    {
        fin >> i >> j;
        X[p] = i; Y[p] = j;
        d[i]++; d[j]++;
        L[i].push_back(p);
        L[j].push_back(p);
    }
}

bool ToatePare()
{
    for (int i = 1; i <= n; i++)
        if (d[i] % 2 == 1) return false;
    return true;
}

void Euler(int k)
{
    while (ind[k] < L[k].size())
    {
        int i = L[k][ ind[k] ];
        ind[k]++;
        if (viz[i] == 0)
        {
            viz[i] = 1;
            Euler(X[i] + Y[i] - k);
        }
    }
    e[++len] = k;
}

void Afis()
{
    for (int i = 1; i < len; i++)
        fout << e[i] << " ";
}

int main()
{
    Citire();
    if (!ToatePare()) fout << "-1\n";
    else
    {
        Euler(1);
        Afis();
    }
    return 0;
}