Cod sursa(job #1252129)

Utilizator radarobertRada Robert Gabriel radarobert Data 30 octombrie 2014 14:24:58
Problema Ciclu Eulerian Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 7.15 kb
#include <iostream>
#include <fstream>

#define MAX_N 100003

template <class TL>
class List
{
    public: struct node
    {
        TL value;
        node *next;
        node *prev;
    };
    private: node *first_node, *last_node;
    private: long long size;

    public: List()
    {
        first_node = last_node = 0;
        size = 0;
    }

    public: long long  Size()
    {
        return size;
    }

    public: node *Begin()
    {
        return first_node;
    }

    public: node *End()
    {
        return last_node;
    }

    public: TL Front()
    {
        return first_node -> value;
    }

    public: TL Back()
    {
        return last_node -> value;
    }

    public: bool isEmpty()
    {
        if (size == 0)
            return 1;
        return 0;
    }

    public: void PushFront(TL x)
    {
        node *q;
        q = new node;
        if (this -> isEmpty())
        {
            q -> value = x;
            q -> prev = q -> next = 0;
            first_node = last_node = q;
            size++;
            return;
        }
        q -> value = x;
        q -> next = first_node;
        q -> prev = 0;
        first_node -> prev = q;
        first_node = q;
        size++;
    }

    public: void PushBack(TL x)
    {
        node *q;
        q = new node;
        if (this -> isEmpty())
        {
            q -> value = x;
            q -> prev = q -> next = 0;
            first_node = last_node = q;
            size++;
            return;
        }
        q -> value = x;
        q -> prev = last_node;
        q -> next = 0;
        last_node -> next = q;
        last_node = q;
        size++;
    }

    public: void PopFront()
    {
        if (this -> isEmpty())
            return;
        node *q;
        q = first_node;
        if (first_node == last_node)
            first_node = last_node = 0;
        else
        {
            first_node = first_node -> next;
            first_node -> prev = 0;
        }
        delete q;
        size--;
    }

    public: void PopBack()
    {
        if (this -> isEmpty())
            return;
        node *q;
        q = last_node;
        if (first_node == last_node)
            first_node = last_node = 0;
        else
        {
            last_node = last_node -> prev;
            last_node -> next = 0;
        }
        delete q;
        size--;
    }

    public: void Erase(node *n)
    {
        if (n == first_node)
        {
            PopFront();
            return;
        }
        if (n == last_node)
        {
            PopBack();
            return;
        }
        n -> prev -> next = n -> next;
        n -> next -> prev = n -> prev;
        delete n;
        size--;
    }
};

template <class TQ>
class Queue
{
    struct node
    {
        TQ value;
        node *next;
    };
    private: node *first_node, *last_node;
    private: long long size;

    public: Queue()
    {
        first_node = last_node = 0;
        size = 0;
    }

    public: long long Size()
    {
        return size;
    }

    public: TQ Front()
    {
        return first_node -> value;
    }

    public: bool isEmpty()
    {
        if (size == 0)
            return 1;
        return 0;
    }

    public: void Push(TQ x)
    {
        node *q;
        q = new node;
        q -> value = x;
        if (this -> isEmpty())
        {
            q -> next = 0;
            first_node = last_node = q;
        }
        else
        {
            last_node -> next = q;
            last_node = q;
        }
        size++;
    }

    public: void Pop()
    {
        if (this -> isEmpty())
            return;
        node *q;
        q = first_node;
        if (first_node == last_node)
                first_node = last_node = 0;
        else
            first_node = first_node -> next;
        delete q;
        size--;
    }
};

template <class TS>
class Stack
{
    struct node
    {
        TS value;
        node *next;
    };
    private: node *top_node;
    private: long long size;

    public: Stack()
    {
        top_node = 0;
        size = 0;
    }

    public: long long Size()
    {
        return size;
    }

    public: TS Top()
    {
        return top_node -> value;
    }

    public: bool isEmpty()
    {
        if (size == 0)
            return 1;
        return 0;
    }

    public: void Push(TS x)
    {
        node *q;
        q = new node;
        q -> value = x;
        q -> next = top_node;
        top_node = q;
        size++;
    }

    public: void Pop()
    {
        if (!this -> isEmpty())
        {
            node *q = top_node;
            top_node = top_node -> next;
            delete q;
            size--;
        }
    }

};

using namespace std;

Stack<int> st;
List<int> nodes[MAX_N];
Queue<int> q;
bool vis[MAX_N];
int n, m;


ofstream out("ciclueuler.out");

void BFS(int x)
{
    vis[x] = 1;
    q.Push(x);
    int cnode;
    while (!q.isEmpty())
    {
        cnode = q.Front();
        for(List<int>::node *i = nodes[cnode].Begin(); i != 0; i = i -> next)
        {
            if (!vis[i -> value])
            {
                vis[i -> value] = 1;
                q.Push(i -> value);
            }
        }
        q.Pop();
    }
}

bool conex()
{
    for (int i = 1; i <= n; ++i)
        if (!vis[i])
            return 0;
    return 1;
}

int eulerian()
{
    for (int i = 1; i <= n; ++i)
    {
        if (nodes[i].Size() % 2 == 1)
            return 0;
    }
    return 1;
}

void deleteEdge(int v, int w)
{
    for(List<int>::node *i = nodes[w].Begin(); i != 0; i = i -> next)
    {
        if (i -> value == v)
        {
            nodes[w].Erase(i);
            break;
        }
    }
    nodes[v].PopFront();
}

void euler(int x)
{
    st.Push(x);
    //out << x;    //fprintf(out, "%d", x);
    int v, w;
    bool first = 1;
    int counter = 0;
    while (counter < m && !st.isEmpty())
    {
        v = st.Top();
        if (nodes[v].isEmpty())
        {
            if (!first)
                out << ' ' << v;
            else
            {
                out << v;
                first = 0;
            }
            st.Pop();
            counter++;
            continue;
        }
        w = nodes[v].Front();
        deleteEdge(v, w);
        st.Push(w);
    }
    out << '\n';
    //out << ' ' << w << '\n';//fprintf(out, " %d\n", w);
}

void solPrint()
{
    if (conex() == false)
    {
        out << "-1\n";    //fprintf(out, "-1\n");
        return;
    }

    int x = eulerian();
    if (x == 1)
        euler(1);
    else
        out << "-1\n";    //fprintf(out, "-1\n");
}

void read()
{
    ifstream in("ciclueuler.in");

    in >> n >> m;    //fscanf(in, "%d%d", &n, &m);

    int x, y;
    for (int i = 1; i <= m; i++)
    {
        in >> x >> y;    //fscanf(in, "%d%d", &x, &y);
        nodes[x].PushBack(y);
        nodes[y].PushBack(x);
    }
}

int main()
{
    read();
    BFS(1);
    solPrint();

    return 0;
}