Cod sursa(job #761962)

Utilizator repp4raduRadu-Andrei Szasz repp4radu Data 28 iunie 2012 01:27:29
Problema Ciclu Eulerian Scor 50
Compilator cpp Status done
Runda Arhiva educationala Marime 2.56 kb
#include <fstream>
#include <vector>
#include <stack>
#include <queue>
#include <set>

#define MAX 100050
#define MAXS 200
#define RST 20

using namespace std;

vector<int> E[MAX][20], L;
set<int> A[MAX];
queue<int> Q; stack<int> S;
int grad[MAX], n;
char rd[MAXS];
bool visited[MAX];

void citire()
{
    ifstream in("ciclueuler.in");
    int m, a, b, i;
    in>>n>>m; in.get();
    while(m--)
    {
        in.getline(rd, MAXS);
        a = 0; b = 0;
        for(i = 0; rd[i] != ' '; i++)
        {
            a = a * 10 + rd[i] - '0';
        }
        for(++i; rd[i] != '\0'; i++)
        {
            b = b * 10 + rd[i] - '0';
        }
        E[a][b % RST].push_back(b);
        E[b][a % RST].push_back(a);
        grad[a]++; grad[b]++;
        A[a].insert(b % RST);
        A[b].insert(a % RST);
    }
    in.close();
}

void bfs(int nod)
{
    Q.push(nod);
    while(!Q.empty())
    {
        int v = Q.front(); Q.pop();
        for(int i = 0; i < RST; i++)
            for(int j = 0; j < E[v][i].size(); j++)
                if(!visited[E[v][i][j]])
                {
                    visited[E[v][i][j]] = true;
                    Q.push(E[v][i][j]);
                }
    }
}

bool isEulerian()
{
    visited[1] = true; bfs(1);
    for(int i = 1; i <= n; i++)
        if(!visited[i] || (grad[i] & 1))
            return false;
    return true;
}

void sterge(int v, int w)
{
    grad[v]--;grad[w]--;
    E[v][w % RST].erase(E[v][w % RST].begin());
    if(!E[v][w % RST].size()) A[v].erase(w % RST);
    for(size_t i = 0; i < E[w][v % RST].size(); i++)
        if(E[w][v % RST][i] == v)
        {
            E[w][v % RST].erase(E[w][v % RST].begin() + i);
            break;
        }
    if(!E[w][v % RST].size()) A[w].erase(v % RST);
}

void euler(int nod)
{
    while(grad[nod])
    {
        set<int>::iterator it = A[nod].begin();
        int stash = *it;
        int v = E[nod][stash][0];
        S.push(nod);
        sterge(nod, v);
        nod = v;
    }
}

bool solve()
{
    if(isEulerian())
    {
        int v = 1;
        do
        {
            euler(v);
            v = S.top(); S.pop();
            L.push_back(v);
        }while(!S.empty());
        return true;
    }
    else
        return false;
}

void afisare(int x)
{
    ofstream out("ciclueuler.out");
    if(x)
        for(size_t i = 0; i < L.size(); i++)
            out<<L[i]<<" ";
    else
        out<<"-1";
    out.close();
}

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