Cod sursa(job #1442940)

Utilizator tweetyMarinescu Ion tweety Data 26 mai 2015 16:10:49
Problema Ciclu Eulerian Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 3.12 kb
#include <fstream>
#include <vector>
#include <cstring>
#include <queue>
#include <stack>
using namespace std;

ifstream In("ciclueuler.in");
ofstream Out("ciclueuler.out");
vector<int>* Neighbours;
vector<int> Solution;
queue<int> Queue;
stack<int> Stack;
int* Grades;
bool* BeenHere;
int NodesNo;
int EdgesNo;
const bool isOriented = false;

void alloc()
{
    Neighbours = new vector<int>[NodesNo];
    Grades = new int[NodesNo];
    BeenHere = new bool[NodesNo];

    memset(Grades, 0, sizeof(int) * NodesNo);
    memset(BeenHere, false, sizeof(bool) * NodesNo);
}

void dealloc()
{
    delete[] Neighbours;
    delete[] Grades;
    delete[] BeenHere;
}

void init()
{

}

void addNeighbour(const int& x, const int& y)
{
    Neighbours[x].push_back(y);
    Grades[x]++;

    if (!isOriented)
    {
        Grades[y]++;
        Neighbours[y].push_back(x);
    }
}

void readData()
{
    In >> NodesNo >> EdgesNo;
    alloc();
    init();

    for (int i = 0, x, y; i != EdgesNo; ++i)
    {
        In >> x >> y;
        addNeighbour(x - 1, y - 1);
    }

    In.close();
}

void printData()
{
    if (Solution.empty())
        Out << "-1";
    else
        for (vector<int>::iterator it = Solution.begin(); it != Solution.end(); ++it)
            Out << *it + 1 << " ";

    Out.close();
}

int removeFromStack()
{
    int x = Stack.top();
    Stack.pop();

    return x;
}

void addToStack(const int& node)
{
    Stack.push(node);
}

void RunThroughGraph(const int& start)
{
    BeenHere[start] = true;
    for (vector<int>::iterator it = Neighbours[start].begin(); it != Neighbours[start].end(); ++it)
        if (!BeenHere[*it])
            RunThroughGraph(*it);
}

bool isConnected()
{
    RunThroughGraph(0);

    for (int i = 1; i != NodesNo; ++i)
        if (!BeenHere[i])
            return false;

    return true;
}

bool isEulerian()
{
    if (!isConnected())
        return false;

    for (int i = 0; i != NodesNo; ++i)
        if (Grades[i] % 2 != 0)
            return false;

    return true;
}

void deleteEdge(const int& from, const int& to)
{
    --Grades[from];
    --Grades[to];

    for (vector<int>::iterator it = Neighbours[from].begin(); it != Neighbours[from].end(); ++it)
        if (*it == to)
        {
            Neighbours[from].erase(it);
            break;
        }

    for (vector<int>::iterator it = Neighbours[to].begin(); it != Neighbours[to].end(); ++it)
        if (*it == from)
        {
            Neighbours[to].erase(it);
            break;
        }
}

void doEulerianShit(int node)
{
    while (!Neighbours[node].empty())
    {
        int second = Neighbours[node][0];

        addToStack(node);
        deleteEdge(node, second);
        node = second;
    }
}

void solve()
{
    if (!isEulerian())
        return;

    doEulerianShit(0);
    while (!Stack.empty())
    {
        int x = removeFromStack();
        Solution.push_back(x);
        doEulerianShit(x);
    }
}

int main()
{
    readData();
    solve();
    printData();
    dealloc();

    return 0;
}